带有路由的 Vanilla Spring Cloud 函数 [英] Vanilla Spring Cloud Function with Routing

查看:104
本文介绍了带有路由的 Vanilla Spring Cloud 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为 Spring Cloud 中的新蜜蜂,我正在开发多功能 Spring Cloud 函数应用程序,该应用程序与 spring-cloud-function-starter-web (3.0.9.RELEASE) 依赖项配合良好.注意:我在不同的包中有不同的功能,并且使用以下配置它可以正常工作.

Being a new bee in Spring cloud, I am developing multi-function spring cloud function application which is working fine with spring-cloud-function-starter-web (3.0.9.RELEASE) dependency. Note: I have different function in different package and with below configuration it is working fine.

cloud:
    function:
        scan:
            packages: zoo.app1.vanilla

例如,使用 [POST] localhost:8080/func1 它调用 Func1 实现 Function.现在我要介绍路由.为此,我只更改了 application.yml

For example, with [POST] localhost:8080/func1 it is invoking Func1 implements Function<I, O>. Now I want to introduce routing. For that I have only changed the below in application.yml

cloud:
    function:
        definition: functionRouter
        routing-expression: headers['function.name']
        scan:
            packages: zoo.app1.vanilla

现在当我调用 using

Now when I invoke 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 具有以下功能

Now when I look into the code I found, RequestProcessor with below function

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 行,它进入无限循环导致计算器溢出错误

It seems like, by default it expects "function.name" in message header in order to route, hence I thought to comment out routing-expression line in application.yml, it is getting into infinite loop resulting in stackoverflow error

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 属性识别我拥有的不同功能吗?请帮忙.另外我还有两个问题,

Am I doing anything wrong? Even if this works, will it recognize the different Functions that I have as per spring.cloud.function.scan.packages property? Please help. Also I have two more questions,

  1. 在一些博客/帖子/文档中,我似乎可以将 spring.cloud.function.definition 作为 http 标头传递.如果这适用于 3.0.9.RELEASE,那么我是否需要在 application.yml 中提及相同的属性?

  1. in some blog/posts/documents it seems I can pass the spring.cloud.function.definition as http header. If this holds true for this 3.0.9.RELEASE, then do I need to mention same property in application.yml?

我可以在不使用 routingFunction 的情况下使用 spring.cloud.function.definition=func1;func2 并期望路由行为正常工作吗?或者这是为了其他功能?

can I use spring.cloud.function.definition=func1;func2 without using routingFunction and expect the routing behaviour working properly? Or this is intended for something other feature?

由于上述问题,我从未测试/尝试过不同的配置选项.请原谅我对spring cloud的一知半解,或者问了一些幼稚的问题.

I have never tested/played around different configuration option because of the above issue. Please forgive my little knowledge on spring cloud or if I have asked any childish question.

编辑

经过调试并在 Spring 文档我找到了正确的配置

After debugging and with help of Spring documentation I found the right configuration

cloud:
    function:
        scan:
            packages: zoo.app1.vanilla
    stream:
        function:
            routing:
                enabled: true

通过此配置,它能够将消息路由到我的函数,但仅限第一次.现在这是让我完全困惑的事情.一旦我启动应用程序并从邮递员那里点击,它就能够识别实际的函数并将输入转换为 GenericMessage 预期(尽管稍后无法解析请求正文).但是当我第二次(及以后)点击时,它甚至无法解析我对 GenericMessage 的输入并给我不同的错误.这是可重复的行为.

With this configuration it is able to route the message to my function, but only for the first time. Now that is something that made me completely confused. Once I start the application and hit from postman, it is able to identify the actual function and converts the input into GenericMessage as expected (though failing to parse request body later). But when I hit second time (and onwards) it is not able to even parse my input to GenericMessage and gives me different error. And this is repeatable behavior.

参考请找连续两次请求的日志(连同postman curl)

For reference Please find the log of two consecutive requests (along with postman curl)

第一个请求:正确路由第二个请求:路由失败

First request : proper routing Second request : routing failure

推荐答案

该问题在 3.1.0.RELEASE 中得到解决,感谢 Oleg Zhurakousky &春季队.参考:问题跟踪器

The issue got resolved in 3.1.0.RELEASE, Thanks Oleg Zhurakousky & Spring team. Ref: Issue Tracker

这篇关于带有路由的 Vanilla Spring Cloud 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆