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つ質問なのですが、
一部のブログ/投稿/ドキュメントでは、
spring.cloud.function.definition
as 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
期待どおりに変換できます (ただし、後で要求本文の解析に失敗します)。しかし、2回目以降にヒットすると、GenericMessageへの入力を解析することさえできず、別のエラーが発生します。そして、これは繰り返し可能な動作です。
参考までに、2 つの連続したリクエストのログを見つけてください (postman curl と一緒に)