2

Spring クラウドの新しいミツバチとして、私は spring-cloud-function-starter-web ( 3.0.9.RELEASE ) 依存関係で正常に動作する多機能 Spring クラウド関数アプリケーションを開発しています。:パッケージごとに異なる機能があり、以下の構成で正常に動作しています。

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ますか? 助けてください。あと2つ質問なのですが、

  1. 一部のブログ/投稿/ドキュメントでは、spring.cloud.function.definitionas http ヘッダーを渡すことができるようです。これがこの 3.0.9.RELEASE に当てはまる場合、application.yml で同じプロパティについて言及する必要がありますか?

  2. 使用spring.cloud.function.definition=func1;func2せずに使用routingFunctionして、ルーティング動作が適切に機能することを期待できますか? それとも、これは何か他の機能を意図したものですか?

上記の問題のため、別の構成オプションをテスト/プレイしたことはありません。春の雲に関する知識が乏しいことや、幼稚な質問をしてしまったことをお許しください。

編集

デバッグ後、Spring ドキュメントの助けを借りて、適切な構成を見つけました

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

この構成では、メッセージを関数にルーティングできますが、初回のみです。今、それは私を完全に混乱させたものです。アプリケーションを起動して郵便配達員からヒットすると、実際の関数を識別し、入力をGenericMessage期待どおりに変換できます (ただし、後で要求本文の解析に失敗します)。しかし、2回目以降にヒットすると、GenericMessageへの入力を解析することさえできず、別のエラーが発生します。そして、これは繰り返し可能な動作です。

参考までに、2 つの連続したリクエストのログを見つけてください (postman curl と一緒に)

最初のリクエスト:適切なルーティング 2 番目のリクエスト:ルーティングの失敗

4

1 に答える 1