【问题标题】:Axon in Java app - reacting to event handler errorsJava 应用程序中的 Axon - 对事件处理程序错误作出反应
【发布时间】:2021-12-27 19:22:51
【问题描述】:

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

这是我的查询...

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

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

对于 Axon 4,我注意到额外的 EventHandlers 正在与处理命令的线程不同的线程中执行,因此可能期望一旦聚合的命令处理程序成功完成命令方法已应用事件 (?)

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

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

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

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

可能的解决方案...?

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

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

谢谢

【问题讨论】:

  • 一些代码示例和对您已经尝试和尝试实现的内容的解释增加了获得问题答案的可能性。 ;-) 这也让读者更容易理解你的意图:-)
  • 嗨 KDW。非常感谢您的出色回应!我是在我有机会在自己的时间与 Axon 一起玩的时候提出这个问题的 :) 我最近没能找到相同的时间,但是感谢您澄清我的一些理解是正确的。为这个措辞冗长的问题道歉,它更多地是关于理解与错误处理相关的概念性东西,我只是部分乐观地认为有人会好心回答。我认为部分问题是我没有正确设置事务管理。

标签: java spring-boot event-handling cqrs axon


【解决方案1】:

我不确定你的问题是否正确。

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

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

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

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

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

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

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

【讨论】:

  • 谢谢。请参阅我的其他评论(回应您的其他评论)。希望我有机会尽快回到这个问题上并找出我的应用程序配置错误的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多