在同一spring boot应用程序中多次收听同一事件时处理轴突中的异常

问题描述 投票:2回答:1

我们正在将轴突集成到我们现有的Spring Boot应用程序中。当前,我们正在使用Axon 4.1.2和Axon Server。

例如,在注册过程中,我们触发一个RegisterCommand,它由RegisterAggregate读取并触发RegistrationDoneEvent

有两个EventHandlers正在收听此RegistrationDoneEvent。分别是RegistrationNeo4jEventHandlerRegistrationSqlEventHandler

没有例外,一切都很好。但是,当发生异常时,假设Neo4JEventHandler接收到事件,并且发生异常,则SqlEventHandler窗台被调用,即使SqlEventHandler仍然看起来一切都回滚了运行成功。

我们如何使SqlEventHandler完成并提交SqlEventHandler重试?

其次,如何在失败后完全停止重试该事件?假设我们有四个事件处理程序(HandlerA,HandlerB,HandlerC,HandlerD)侦听SAME事件。如果HandlerC失败,则当我们说修复了基本问题时,我们想触发它进行重试,但还要确保侦听SAME事件的其他处理程序不会重新运行。

以下代码片段包括聚合和事件处理程序。

RegisterAggregate

Neo4JEventHandler

RegistrationSqlEventHandler

@Aggregate
public class RegisterAggregate {

    ....

    @CommandHandler
    public RegisterAggregate(RegisterCommand command) {
        apply(new RegistrationDoneEvent(command));
    }
}

RegistrationNeo4jEventHandler

@Service
@Transactional
public class RegistrationSqlEventHandler { 

    @EventHandler
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public void on(RegistrationDoneEvent event) {
        ....
    }
}
java spring spring-boot cqrs axon
1个回答
2
投票

我将我的回答分成两个部分,因为您提出的不是一个问题,而是两个问题。首先,让我们谈谈您的问题:

我们如何使@Service @Transactional public class RegistrationNeo4jEventHandler { @EventHandler public void on(RegistrationDoneEvent event) { .... } } 完成并提交RegistrationSqlEventHandler重试?

从命名开始,两个事件处理组件(即包含RegistrationNeo4jEventHandler批注方法的类you写入)已经非常明显地服务于完全不同的查询模型。第一个目标是RDBMS,第二个目标是通过Neo4j更新图模型。

因此,我发现您最终很有可能对这两种功能都有不同的非功能性要求。为了能够对它们进行不同的配置,您将必须为两者使用不同的@EventHandler实例。事件处理器,负责管理将事件提供给your事件处理程序的技术方面的组件,作为配置诸如异常处理,线程号,批处理大小等内容的位置。>

请注意,事件处理器有两种形式:Event ProcessorSubscribingEventProcessor。可以将它们简短地描述为事件推送和事件拉动机制,后者是默认机制,因为它会进一步隔离。

要为两者配置不同的事件处理器,您可以使用Axon提供的配置API。对于事件处理器,这意味着与TrackingEventProcessor进行交互。使用它,您可以定义不同的事件处理器,然后将事件处理组件分配给正确的实例。您可以采用的一种简便方法是在两个事件处理组件上添加EventProcessingConfigurer批注,并在其中添加不同的名称。尤其是在Spring Boot环境中,就配置而言就足够了。

进行此隔离将确保@ProcessingGroup中的异常情况不会对RegistrationNeo4jEventHandler产生任何不希望的影响,反之亦然。


第二,让我们转到另一个问题:

第二,如何在失败后完全停止重试事件?

为此,您必须调整事件处理过程的异常处理。关于事件处理组件,Axon派生了两个级别的异常处理:

  1. RegistrationSqlEventHandler->负责处理由ListenerInvocationErrorHandler带注释的方法引发的异常。
  2. @EventHandler->负责处理在事件处理器中[[内部
  3. 引发的异常。这些的默认实现将分别记录错误(使用ErrorHandler)并传播异常(使用LoggingErrorHandler)。

FYI,参考指南中的PropagatingErrorHandler表示事件处理器的错误处理。

在此问题中,您将通过不同的事件处理功能进一步指定案件。同样,如果您不想影响某个事件处理的失败而导致另一事件的问题,则可能需要将这些关注点与不同的事件处理器分开。

不过请记住,如果您要例示的这四个事件处理程序只是在更新查询模型,则后续调用应仅执行相同的操作而没有任何副作用。但是,如果这些事件处理程序执行其他一些(外部)活动,例如发送电子邮件,则绝对可以保证将给定的事件处理组件隔离到一个您不想重试/重播的独立事件处理器中。

© www.soinside.com 2019 - 2024. All rights reserved.