Axon 服务器命令不包含路由键
Posted
技术标签:
【中文标题】Axon 服务器命令不包含路由键【英文标题】:Axon Server Command does not contain routing key 【发布时间】:2019-04-18 03:19:57 【问题描述】:我正在尝试使用 Axon 服务器将我的应用程序迁移到 Axon 4.0。 这是我的代码。
data class CreateTravelProductCommand(
@TargetAggregateIdentifier val id: String,
val productCreator: String
)
val id: String = ObjectId.get().toString()
val command = CreateTravelProductCommand(id=id, productCreator=request.creator)
commandGateway.sendAndWait(command)
但是我的命令出现了这个错误。
org.axonframework.commandhandling.distributed.CommandDispatchException: 命令 [com.sunday.api.product.CreateTravelProductCommand] 确实 不包含路由键。 在 org.axonframework.commandhandling.distributed.AbstractRoutingStrategy.getRoutingKey(AbstractRoutingStrategy.java:57) ~[axon-messaging-4.0.jar:4.0] 在 org.axonframework.axonserver.connector.command.AxonServerCommandBus.dispatch(AxonServerCommandBus.java:114) ~[axon-server-connector-4.0.jar:4.0] 在 org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:75) [axon-messaging-4.0.jar:4.0] 在 org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:78) [axon-messaging-4.0.jar:4.0] 在 org.axonframework.commandhandling.gateway.DefaultCommandGateway.sendAndWait(DefaultCommandGateway.java:96) [axon-messaging-4.0.jar:4.0] 在 com.sunday.underwriting.product.ProductHandler.sendCreateProductCommand(ProductHandler.kt:40) [类/:na] 在 com.sunday.underwriting.product.ProductHandler.access$sendCreateProductCommand(ProductHandler.kt:33) [类/:na] 在 com.sunday.underwriting.product.ProductHandler$createProduct$product$1.invoke(ProductHandler.kt:97) [类/:na] 在 com.sunday.underwriting.product.ProductHandler$createProduct$product$1.invoke(ProductHandler.kt:33) [类/:na] 在 com.sunday.underwriting.product.ProductHandler$sam$java_util_function_Function$0.apply(ProductHandler.kt) [类/:na] 在 reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1476) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:794) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:560) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:540) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:426) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.DrainUtils.postCompleteDrain(DrainUtils.java:131) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.DrainUtils.postComplete(DrainUtils.java:186) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxMapSignal$FluxMapSignalSubscriber.onComplete(FluxMapSignal.java:213) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE] 在 reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:378) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:202) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:343) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:325) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:442) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:141) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:188) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) [netty-codec-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) [netty-codec-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized (NioEventLoop.java:563) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [netty-transport-4.1.29.Final.jar:4.1.29.Final] 在 io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-common-4.1.29.Final.jar:4.1.29.Final] 在 java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]
编辑:
我刚刚发现,如果你把这个类放在同一个项目中,就可以了。
问题是当你从另一个项目中导入类时(这在轴突服务器之前曾经工作过)
例如:
我的项目依赖于另一个名为 api 的项目。
dependencies
compile project(':api')
如果在 api 项目中声明了类,axon 服务器库会抛出找不到路由键的错误。但是,如果该类是在它自己的主项目中声明的,它会按预期工作。我想我应该在 github 上提交这个问题。
【问题讨论】:
【参考方案1】:真正的问题是 2 个项目之间的版本不匹配。我必须更正版本,但 intellij 自动加载器不起作用,并且 api 项目的版本不正确。
我为我的愚蠢道歉
【讨论】:
【参考方案2】:从 Axon 3.x 迁移到 4.0 时,我遇到了同样的问题。
该解决方案与@TargetAggregateIdentifier
有关 - 我在聚合处理的“CreateXXXCommand”中遗漏了它。我很确定在 Axon 3.x 中添加 @TargetAggregateIdentifier
不是创建命令所必需的(因为它不必定位现有的聚合)
在撰写本文时,迁移指南不完整 https://docs.axoniq.io/reference-guide/3-migration/migration-guide
【讨论】:
【参考方案3】:这实际上与 Kotlin 的关系比与 Axon 的关系更大。 Axon 期望它们使用 Field 或 Getter 方法。显然,这不是 Kotlin 将它们默认放置的地方。
查看https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets
您可能需要使用@get:TargetAggregateIdentifier
注释属性
【讨论】:
以上是关于Axon 服务器命令不包含路由键的主要内容,如果未能解决你的问题,请参考以下文章
译见 | 用 Docker,Spring Boot/Cloud 和 Axon CQRS/ES(事件溯源)来构建微服务
服务/软件管理:06---Linux查看主机路由(route命令)