EDA微服务架构也要使用命令 - Scaramuzzi


微服务架构是开发具有竞争力的软件平台的基准,基于松散耦合的服务,易于更改、部署、横向扩展,同时也将更改和部署的风险降至最低。
与 REST 同步调用相比,事件驱动是服务内通信,应该避免服务之间的耦合。但是,如果我们在设计上不小心,我们仍然可以通过使用事件来开发高度耦合的微服务。这将导致构建分布式单体架构,这比纯单体架构差得多。

事件通知非常自然,因为它意味着低级别的耦合并且设置起来非常简单。一般来说,当有几个微服务相互交互时,该解决方案是易于管理的,但当微服务数量增加时,它可能会出现问题。
下面列出了将我们的事件驱动架构仅基于事件时发生的两个常见问题:

  1. 当存在运行在各种事件上的逻辑流时,可能很难区分这样的流,因为它在任何程序文本中都不是明确的。这会给流程的修改和调试带来挑战。因此,了解流程的唯一方法是通过监控实时系统。
  2. “微服务 A ”期望“微服务 B ”作为“微服务 A ”业务逻辑的一部分。如果这是通过让“微服务 A ”引发事件然后“微服务 B ” 订阅事件来开发的,那么我们就是将属于“微服务 A”的业务逻辑传播并耦合到“微服务 B”中。

主要问题是,在事件驱动的架构中,事件和命令消息之间通常没有区别。

大多数时候,与命令相比,事件被过度使用。下面列出了事件和命令之间的区别。

  • 命令:目的是在特定边界内调用与业务逻辑相关的行为。命令有一个消费者。它们由动词表示(SendEmail、PlaceOrder、ReservePayment 等)。
  • 事件:目的是提醒系统的其他部分在特定边界下发生了某些事情。事件可以是命令完成的结果。事件有多个位于不同边界下的消费者。事件以过去时表示(EmailSent、OrderPlaced、PaymentReserved 等)。

应该正确使用这两种类型的消息,并且良好的架构应该在事件和命令之间取得适当的平衡。

通过命令进行事件驱动的用例
作为 NA-KD 电子商务平台现代化之旅的一部分,为了实现某些业务目标,已经逐渐转向微服务架构。我们开发了“全局通知服务”微服务,旨在集中、改进和管理多个子域的多个服务请求的电子邮件发送。目标是利用此服务发送电子邮件以进行用户密码重置、订单确认、发货确认、库存通知等。

理所当然地认为,对于这些类型的用例,异步发送通知是有利的,“简单”的解决方案“显然”是让全局通知服务订阅所有想要发送的服务发布的不同事件通知。

让我们来看看为什么在这种情况下,基于事件的方法不是最好的解决方案。

  • 在NA-KD域中,发送电子邮件是子域中业务逻辑的一部分。例如,在订单服务中,当支付预订失败时,知道是否向客户发送了电子邮件是很重要的。
  • 拥有一个纯粹基于事件的解决方案是将通知服务与许多不同的子域耦合在一起。例如,通知服务需要知道,当一个订单被总结和更新时,必须发送电子邮件。
  • 每次有新的服务需要发送通知时,就必须对通知服务进行更改。

对全局通知服务使用事件,恰恰引发了上段所述的两个问题。相反,应该在命令上利用一个更可扩展和松散耦合的方法。

而通过使用命令:

  • 所有需要发送电子邮件的服务都在业务逻辑的控制之下。
  • 通知服务只负责发送和管理电子邮件。它与其他子域相关的业务逻辑是不可知的。

banq注:这是一个上下文边界设计问题,如果BC设计到位,不会将当前业务逻辑泄漏到其他边界,做好几个不同BC之间的映射,这种映射最终体现在命令或事件上