【问题标题】:Best Practices for Micro-service interaction with Event-Sourcing (CQRS)微服务与事件溯源(CQRS)交互的最佳实践
【发布时间】:2019-08-16 15:33:54
【问题描述】:
我有一个 API 调用需要处理多个聚合。关于它应该如何与聚合进行交互,我有以下 2 个想法,但我对其他想法持开放态度。
将命令从一个微服务发送到另一个微服务是一种好习惯吗?还是在微服务 B 上有一个事件处理程序来响应来自服务 A 的事件并在微服务 B 内生成所有命令是否更好?
【问题讨论】:
标签:
java
domain-driven-design
microservices
cqrs
event-sourcing
【解决方案1】:
将命令从一个微服务发送到另一个微服务是一种好习惯吗?还是在微服务 B 上有一个事件处理程序来响应来自服务 A 的事件并在微服务 B 内生成所有命令是否更好?
在服务架构中需要认识到的重要一点:我们希望服务是自治的。所以A 应该在B 停机维护时继续工作,反之亦然。
这意味着我们需要支持从 A 到 B 的异步消息传递。
当前的“最佳实践”是您正在处理异步传递的消息,那么语义应该是过去时:SomethingHappenedA,B 将对其做出反应,或者不对其做出反应时间自行决定。
这有关系吗?很难说——handle(Event) 是一个命令,CommandReceived 是一个事件。
注意:这实际上只是服务和消息传递——Event-Sourcing/CQRS 真的不参与其中。
Martin Fowler 在 2005 年描述了 Domain Events。
每个领域事件都从外部刺激中捕获信息。
如果您认为A 是B 的外部(这是有道理的,如果它们之间存在服务边界),那么域事件模式的语义可能是一个非常很合身。
【解决方案2】:
为什么不两者兼而有之?
我对这些“微服务”的处理方式略有不同。我通常为每个有界上下文都有一个消息传递端点。我想这很符合微服务的想法,并且 that 端点只响应发送给它的适用于该 BC 的命令。然后它还会发布相关事件。
然后我可能也拥有一个编排端点,它响应“属于”相关BC的流程管理器。该端点仅处理流程管理器的状态,并向需要与之通信的任何 BC 消息传递端点发出命令。例如,在收到OrderRegisteredEvent 之后,可能会发出SendEMailCommand。好吧,这更像是一个技术端点/BC,但仍然如此。
在仅 BC 的消息传递端点上,不同的 BC 之间绝对没有。它仅在那里为自己的 BC 提供服务。
我希望这是有道理的。