关于事件驱动拓扑中的中介

Edw*_*rzo 5 events event-driven-design event-driven orchestration microservices

我正在阅读这篇文章,称为事件驱动架构中的变体,它们演示了中介和代理拓扑.

根据文章,中介拓扑看起来有点像这样:

中介拓扑

事件流开始于客户端将事件发送到事件队列,该事件队列用于将事件传输到介体.该事件介体接收初始事件,并通过发送附加异步事件编排该事件的事件通道以执行该过程的每个步骤.监听事件通道的事件处理器从偶数调解器接收事件并执行特定的业务逻辑来处理事件[...]重要的是要注意事件调解器实际上并不执行必要的业务逻辑处理初始事件,而不是它知道处理事件所需的步骤[...]事件通道可以是消息队列o消息主题.

所以,我正在研究这个图,试图理解中介如何确定给定处理器何时完成处理给定事件,以便它可以协调下一步的过程.

它说的文章不够清楚

对于每个初始事件步骤,事件中介器创建处理事件,发送该处理事件并等待相应事件处理器处理处理事件.此过程将继续,直到处理完初始事件中的所有步骤.

现在,文章清楚地表明通信是异步的,并且事件消息将通过消息队列传播,但该图不显示从事件处理器发出并返回到调解器的任何事件.

文章说调解员等待事件处理器完成,但目前尚不清楚这应该如何在架构方面发生.

它是异步的,基于队列的RPC(例如Rabbit RPC),还是有另一个侦听器在某处等待异步响应?

有关如何从架构的角度实现这一点的任何想法?

Mik*_* B. 6

在我看来,他们只是没有绘制从事件处理器返回的事件,也许是因为它们可能不是特定的事件(如某种回调),或者因为它们可能不是正常事件(也许是只返回的事件)对中介者可见,并且对任何其他订阅者不可见),具体取决于您用作中介者的内容。这部分似乎表明了类似的事情:

事件中介器可以通过多种方式实现。了解每个实施选项,以确保您为事件中介器选择的解决方案符合您的需求。

事件中介器最简单且最常见的实现是通过开源集成中心,例如 Spring Integration、Apache Camel 或 Mule ESB。这些开源集成中心中的事件流通常通过 Java 代码或 DSL(特定于领域的语言)来实现。对于更复杂的中介和编排,您可以将 BPEL(业务流程执行语言)与 BPEL 引擎(例如开源 Apache ODE)结合使用。BPEL 是一种标准的类似 XML 的语言,它描述了处理初始事件所需的数据和步骤。对于需要更复杂的编排(包括涉及人工交互的步骤)的大型应用程序,您可以使用业务流程管理器(BPM)(例如jBPM)来实现事件中介器。

了解您的需求并将其与正确的事件中介器实现相匹配对于使用此拓扑的任何事件驱动架构的成功至关重要。使用开源集成中心进行非常复杂的业务流程管理编排是失败的秘诀,就像实施 BPM 解决方案来执行简单的路由逻辑一样。

他们提到 Spring 作为一种可能的实现 - 我从未使用过它,但查看文档(此处)我看到了回复通道的概念:

...当服务方法返回非空值时,端点将尝试将回复消息发送到适当的回复通道。


目标是发送一条或多条消息进行异步处理,然后在结果返回时发送其他消息。我认为在模式级别,这些结果如何返回(函数回调、“响应”事件、Web API 调用等)并不那么重要——这将取决于您的特定基础设施。

对我来说,这听起来有点像 Saga 模式(链接)。在这种情况下,Saga(或中介者)知道完成某些任务所需的步骤,并维护有关该任务进度的某些状态。

它发出要处理的命令并监听响应。当响应(事件)到来时,它会更新其状态,然后使用其状态来确定接下来需要触发哪些命令。

这种情况一直持续到 A) 过程完成,或 B) 过程中的某个步骤失败(在这种情况下,它可能会反转方向并开始触发补偿命令以“撤消”先前的操作)。

使用您引用的帖子中的下图,传奇/调解者的“想法”可能是沿着......

  1. 重定位事件,因此触发更改地址命令并等待。
  2. 收到地址更改事件。现在我已经更改了地址,但我还没有重新计算报价或更新索赔,所以我将把它们发送出去(它们不冲突,所以都发送)并等待。
  3. 收到 ClaimsUpdated 事件。在继续之前仍需要重新计算,所以请继续等待。
  4. 收到 QuoteRecalced 事件。现在我已经更新了地址、重新计算了报价并更新了索赔,我可以发送“调整索赔”命令,然后等待。

... 等等。

您可能想要添加持久性(以便在发生崩溃时可以从中断处继续)、幂等事件处理器(以便重播事件不会导致问题)和/或超时(以免永远等待如果响应事件丢失/丢失)。

图表


Ten*_*giz 5

我想你在图上已经有了答案:

初始事件步骤(红色)是关键。每个事件处理器都会生成一个事件,该事件进入事件队列,然后到达事件中介器。

该架构是事件驱动且异步的。单个事件队列处理事件中介器的路径。由于这是将事件发送到事件中介器的唯一方法,因此显然,任何想要将事件发送到中介器的东西都需要使用此路径。

在某个事件发生后的某个时刻,事件中介器将声明该操作已成功完成,并且不会向事件处理器调度更多事件。

虽然,我必须说,你是对的,但文章中没有明确说明这一点。我认为他们正在预览的书中会更好地阐明这一点。