繁体   English   中英

Java 应用程序中的 Axon - 对事件处理程序错误作出反应

[英]Axon in Java app - reacting to event handler errors

抱歉,如果这已经涵盖,我是 Axon 的新手,我相信我已经阅读了相关的 Axon 文档并扫描了问题,但没有找到任何涵盖我的问题的内容。

这是我的查询...

使用 Axon,我知道我可以创建一个命令,将其发送到网关,然后将其转发到正确的聚合,然后应用一两个事件。 然后这些事件被持久化并可选择地传递给其他事件处理程序。

(请注意,在我的例子中,我使用的是带有EmbeddedEventStoreSimpleCommandBusJdbcEventStorageEngine的 Spring Boot)。

使用 Axon 4,我注意到额外的EventHandler正在与处理命令的线程不同的线程中执行,因此可以推测,一旦聚合的命令处理程序方法应用了事件,命令就会成功完成(?)

我的问题真正归结为:使用 Axon 的系统如何(或应该)处理这些下游事件处理程序中的错误?

例如,下游处理程序可能会调用另一个 API - 如果该请求失败会发生什么,Axon 是否有内置的东西为此提供了良好的约定?

在非基于 CQRS/Axon 的应用程序中,我想这主要是通过使用外部消息总线来托管事件消息并根据新消息触发消费者来执行的。 XA 事务可用于确保数据一致性(例如,将数据写入数据库,将消息添加到队列)。 我不确定 XA 交易是否仍然被广泛接受——考虑到微服务如何变得更加突出。

对于 Axon,我怀疑命令已成功完成,即使下游事件处理程序之一失败。 我了解 Axon 正试图将这两个问题完全分开。

可能的解决方案...?

我可以引入外部消息总线或数据库来存储失败的事件并重试它们,但我不禁认为这是重复 Axon 已经在做的事情——存储事件并执行代码以响应事件。 序列化一个事件,发送到一个队列(也可能失败)似乎需要做很多工作,然后才被使用,然后在应用程序中重新播放。 即使我将相同的事件反序列化为EventMessage ,我也不确定如何重新调用相同的处理程序。

请问有人对此有什么想法吗? 也许我完全错过了 CQRS 和 Axon 的重点,并且以错误的方式处理事情。 如果是这种情况,请更正:)。

谢谢

我不确定是否正确理解您的问题。

我的问题真正归结为:使用 Axon 的系统如何(或应该)处理这些下游事件处理程序中的错误?

一旦带注释的方法正常终止,下游事件处理程序(我假设一个单独的类实现一个或多个@EventHandler方法)将事件标记为“已使用”。 如果在方法执行过程中抛出异常,则认为该事件未消费。 如果配置为使用持久令牌存储​​,Axon 会跟踪已处理的事件,并在先前通过 EventHandler 方法处理事件的请求失败时重试。 它一直在尝试,直到最终被消耗掉。

使用 Axon,我知道我可以创建一个命令,将其发送到网关,然后将其转发到正确的聚合,然后应用一两个事件。 然后这些事件被持久化并可选择地传递给其他事件处理程序。

如果您的意思是“事件随后被持久化”,那么当调用AggregateLifecycle.apply方法将事件作为参数传递时,事件将被持久化,那么您是对的。 然后,该事件将持久保存在其他线程正在“扫描”的事件存储中,以通知@EventHanlder注释方法。

对于 Axon 4,我注意到额外的 EventHandler 正在与处理命令的线程不同的线程中执行,因此可以推测,一旦 Aggregate 的命令处理程序方法应用了事件( ?)

正确的! 请记住,尽管命令是“一劳永逸”。 它们不存储在某种命令存储中。 如果命令处理程序由于某种原因无法完成或失败,那么糟糕......应该通过发送新命令来重试。 命令是对聚合执行某些状态更改操作但从不更改状态本身的请求。 由聚合决定是否允许根据其当前状态更新此状态。 如果是这样,则聚合发出将存储在事件存储中的事件。 该事件将再次被更新状态的聚合的@EventSourcingHandler捕获。 如果请求无效,则不应用任何事件,并且命令方法通常会终止,而忘记命令已发送。

希望这能澄清你的一些问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM