Axon amqp 消息传递,未触发事件处理程序

Axon amqp messaging, event handler not triggered

所以我正在开发我的第一个 Axon 应用程序。到目前为止,我让整个轴突项目都在单体中运行。之后,我开始使用 Sprint Boot 中的 @Profile 将应用程序分成几部分。也很有魅力。所以我的下一步是完全分布式并为我的 Axon 流程使用 2 个完全不同的 intellij 项目。在这里我遇到了一个问题。我使用 AMQP 来传递事件消息。使用文档中的信息,我可以从一项服务获取事件到另一项服务。但是事件处理程序没有被触发。我想问题是因为事件的类型。第一个服务发送如下事件:com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent。但是我在其他项目中的事件处理程序会监听:com.checkInService.CheckIn.Service.coreapi.events.CheckIn.CheckedInEvent。我猜这就是事件处理程序未被触发的原因,但我不确定?

amqp 的所有其他配置都已正确设置,我还将 ampqmessagesource 连接到我的 processingroup。

所以我的问题是,是否可能因为 checkedInEvent 有 2 个不同的路径而未触发事件处理程序?如果是这样,我该如何解决?

你的假设确实是正确的。您的 EventHandler 的 payloadType 与发出的事件不匹配。您的 EventHandler 方法注册它可以处理类型为 com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent 的事件。但是,通过 rabbit 发送的事件是类型 com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent,没有注册处理程序。

对于任何 EventHandler,要求 (super)类 与发出的内容匹配,其中包括包名称。可以在文档中找到更详细的解释 (https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/handling-events):

In all circumstances, at most one event handler method is invoked per listener instance. Axon will search for the most specific method to invoke, using following rules:

  1. On the actual instance level of the class hierarchy (as returned by this.getClass()), all annotated methods are evaluated

  2. If one or more methods are found of which all parameters can be resolved to a value, the method with the most specific type is chosen and invoked

  3. If no methods are found on this level of the class hierarchy, the super type is evaluated the same way

  4. When the top level of the hierarchy is reached, and no suitable event handler is found, the event is ignored.

我的建议是使用发出事件的服务的完全限定名称,在您的情况下是 com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent。即使您在其中处理事件的服务位于不同的限界上下文中,您仍在处理属于发出该事件的限界上下文的事件。让你的包结构反映出来让你的代码更具可读性。

@ViveTech 为您提供了解决问题的正确建议,但我想在这里补充一点。

消息,在本例中为事件,是应用程序之间的 public API。因为它是 public,所以它 could/should 在存储库之间作为 "core API" module/package.

共享

将事件格式(又名实施)复制到两个项目都有效,但就像您已经说过的那样,这是一个相当草率的解决方案。 共享一个专用的核心 API 模块我认为会更好地满足您的目的。

如果您不想在共享库中共享此 "implicit schema"(又名事件的实现),您可以调整框架中的 Serializer 以使用 [=31= 的别名] 名字。

您可以提供给 XStreamSerializerXStream 实例为别名提供了很好的句柄,对于 JacksonSerializer 您将不得不使用 ObjectMapper .