问题描述
作为Spring Cloud的新蜜蜂,我正在开发多功能Spring Cloud功能应用程序,该应用程序可以很好地与spring-cloud-function-starter-web( 3.0.9.RELEASE )依赖项一起使用。 注意:我在不同的程序包中具有不同的功能,并且使用以下配置,效果很好。
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
现在当我使用调用时
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”进行路由,因此我想注释掉application.yml中的routing-expression
行,它进入了无限循环,从而导致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 documentation的帮助下,我找到了正确的配置
cloud:
function:
scan:
packages: zoo.app1.vanilla
stream:
function:
routing:
enabled: true
使用此配置,它可以将邮件路由到我的功能,但仅限第一次。现在,这让我完全感到困惑。一旦我启动了应用程序并从邮递员那里找到了它,它就可以识别实际的功能,并将输入按预期方式转换为Genericmessage
(尽管稍后无法解析请求正文)。但是,当我第二次(及以后)命中时,它甚至无法解析我对Genericmessage的输入,并给了我不同的错误。这是可重复的行为。
作为参考,请找到两个连续请求的日志(以及邮递员curl)
第一个请求:proper routing 第二个请求:routing failure
解决方法
此问题已在3.1.0.RELEASE中解决,谢谢Oleg Zhurakousky和Spring团队。 参考:Issue Tracker