作为 Spring Cloud 中的新成员,我正在开发与 spring-cloud-function-starter-web ( 3.0.9.RELEASE ) 依赖关系良好的多功能 Spring Cloud 功能应用程序。注意:我在不同的包中有不同的功能,下面的配置可以正常工作。
cloud:
function:
scan:
packages: zoo.app1.vanilla
例如,[POST] localhost:8080/func1
它正在调用Func1 implements Function<I, O>
. 现在我要介绍路由。为此,我只更改了以下内容application.yml
cloud:
function:
definition: functionRouter
routing-expression: headers['function.name']
scan:
packages: zoo.app1.vanilla
现在当我调用 using
curl --location --request POST 'http://localhost:8080/functionRouter' \
--header 'function.name: func1' \
--header 'Content-Type: text/plain' \
--data-raw '1'
例外是
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'headers' cannot be found on object of type 'reactor.core.publisher.FluxMapFuseable' - maybe not public or not valid?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:91) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:375) ~[spring-expression-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.cloud.function.context.config.RoutingFunction.functionFromExpression(RoutingFunction.java:173)
现在,当我查看找到的代码时,RequestProcessor
具有以下功能
private Object getTargetIfRouting(FunctionWrapper wrapper, Object function) {
if (function instanceof RoutingFunction) {
String name = wrapper.headers.get("function.name").iterator().next();
function = this.functionCatalog.lookup(name);
}
return function;
}
看起来,默认情况下,它需要消息头中的“function.name”以便路由,因此我想routing-expression
在 application.yml 中注释掉行,它进入无限循环导致 stackoverflow 错误
2020-08-13 11:47:16.454 DEBUG 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Applying function: functionRouter
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Looking up function 'functionRouter' with acceptedOutputTypes: []
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.context.config.RoutingFunction : Resolved function from provided [definition] property functionRouter
2020-08-13 11:47:16.454 DEBUG 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Applying function: functionRouter
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Looking up function 'functionRouter' with acceptedOutputTypes: []
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.context.config.RoutingFunction : Resolved function from provided [definition] property functionRouter
2020-08-13 11:47:16.454 DEBUG 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Applying function: functionRouter
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Looking up function 'functionRouter' with acceptedOutputTypes: []
2020-08-13 11:47:16.454 INFO 85560 --- [nio-8080-exec-1] o.s.c.f.context.config.RoutingFunction : Resolved function from provided [definition] property functionRouter
2020-08-13 11:47:16.454 DEBUG 85560 --- [nio-8080-exec-1] o.s.c.f.c.c.SimpleFunctionRegistry : Applying function: functionRouter
2020-08-13 11:47:16.468 ERROR 85560 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
我做错什么了吗?即使这可行,它会根据spring.cloud.function.scan.packages
属性识别我拥有的不同功能吗?请帮忙。另外我还有两个问题,
在一些博客/帖子/文档中,我似乎可以通过
spring.cloud.function.definition
http 标头。如果这适用于这个 3.0.9.RELEASE,那么我是否需要在 application.yml 中提及相同的属性?我可以
spring.cloud.function.definition=func1;func2
在不使用的情况下使用routingFunction
并期望路由行为正常工作吗?或者这是为了其他功能?
由于上述问题,我从未测试/玩过不同的配置选项。请原谅我对春云的一点了解,或者如果我问了任何幼稚的问题。
编辑
经过调试并在Spring 文档的帮助下,我找到了正确的配置
cloud:
function:
scan:
packages: zoo.app1.vanilla
stream:
function:
routing:
enabled: true
使用此配置,它能够将消息路由到我的函数,但仅限于第一次。现在,这让我完全困惑。一旦我启动应用程序并从邮递员那里点击,它就能够识别实际功能并将输入转换GenericMessage
为预期的(尽管稍后无法解析请求正文)。但是当我第二次(及以后)点击时,它甚至无法解析我对 GenericMessage 的输入并给我不同的错误。这是可重复的行为。
供参考请找到两个连续请求的日志(连同邮递员卷曲)