为什么 Axon Framework 中的 RetryScheduler 在 NoHandlerForCommandException 后不重试?

Why does the RetryScheduler in Axon Framework not retry after a NoHandlerForCommandException?

所以我有一个 Saga,Saga 在特定事件上向不同的微服务发送命令。我想用 RetryScheduler 配置 commandGateway,以便它在其他微服务关闭时重试发送命令。 RetryScheduler 只会在异常是 RuntimeException 时执行重试,而当其他服务离线时抛出的 NoHandlerForCommandException 肯定是。

如果我不设置 maxRetryCount,则错误消息为
o.a.c.gateway.IntervalRetryScheduler:命令 [XXXCommand] 的处理导致异常 1 次。永久放弃

如果我确实设置了该属性,错误消息是
o.a.c.gateway.IntervalRetryScheduler:命令 [XXXCommand] 的处理导致异常,不会重试

如果另一个微服务是运行,则命令处理正确,没有问题。

有人知道问题出在哪里吗?

这是我对带有 RetryScheduler 的 commandGateway 的配置:

@Bean
public CommandGateway commandGateway(){

    Configurer configurer = DefaultConfigurer.defaultConfiguration();

    CommandBus commandBus = configurer.buildConfiguration().commandBus();

    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    RetryScheduler rs = IntervalRetryScheduler.builder().retryExecutor(scheduledExecutorService).maxRetryCount(100).retryInterval(1000).build();
    CommandGateway commandGateway = DefaultCommandGateway.builder().commandBus(commandBus).retryScheduler(rs).build();

    return commandGateway;
}

要解决手头的问题,您可以提供自己的 IntervalRetryScheduler 实现,它会覆盖 IntervalRetryScheduler#isExplicitlyNonTransient(Throwable) 方法以同时考虑重试 NoHandlerForCommandException

请注意,尽管 IntervalRetryScheduler 有意仅重试类型为 AxonNonTransientException 的异常,但那些通常表示可恢复的异常。 NoHandlerForCommandException 意味着正在使用的 CommandBus 实现也不知道向谁发出命令,这通常表明无法重试。

不过,您似乎有一个确实有意义的场景。因此,就像我在开始时指出的那样,覆盖 isExplicitlyNonTransient(Throwable) 方法以排除 NoHandlerForCommandException 将是我认为适合你的方法。

希望对您有所帮助!