如何在事件驱动架构中处理相关事件?具体来说,如果必须触发多个事件才能执行某些操作怎么办。例如,我有一个微服务,它监听两个事件foo
,bar
并且仅在两个事件都到达并具有相同的关联 ID 时才执行操作。
一种方法是在进行簿记的微服务内部保留一个内部数据结构,当一切都得到满足时,就会触发适当的操作。然而,这种方法的问题在于微服务不再是不可变的。
有更好的方法吗?
如何在事件驱动架构中处理相关事件?具体来说,如果必须触发多个事件才能执行某些操作怎么办。例如,我有一个微服务,它监听两个事件foo
,bar
并且仅在两个事件都到达并具有相同的关联 ID 时才执行操作。
一种方法是在进行簿记的微服务内部保留一个内部数据结构,当一切都得到满足时,就会触发适当的操作。然而,这种方法的问题在于微服务不再是不可变的。
有更好的方法吗?
一个典型的例子是在销售时收到订单并发布事件。Finance 和 Shipping 都订阅了该事件,但 shipping 也订阅了来自财务的事件。
有趣的是,您不知道消息到达的顺序。来自销售的事件可能会导致技术错误,因为数据库处于脱机状态。它可能会再次排队或最终进入错误队列以进行重试操作。与此同时,来自金融的事件可能会到来。所以理论上销售事件应该先到达,然后是金融事件,但实际上它可以反过来。
这里有很多解决方案,但我从不喜欢图形化的解决方案。作为 .NET 开发人员,我过去使用过 K2 和 Windows Workflow Foundation,但最灵活的解决方案是在代码中创建的,而不是通过图形界面。
我目前会为此使用 NServiceBus 或 MassTransit。顺便说一句,我目前在 Particular Software 工作,我们制作 NServiceBus。NServiceBus 为此类工作提供了 Sagas(文档),您还可以在我的博客上阅读有关演示文稿的内容,包括。GitHub上的代码。
该术语saga
有点加载,但它基本上处理长时间运行的(业务)流程。Gregor Hohpe 称之为Process Manager
(链接)。
总结一下 sagas 的作用:它们由传入消息实例化并具有状态。传入消息根据相关 ID 绑定/分派到特定的 saga 实例,例如 acustomer id
或order id
。一旦消息(事件)被处理,状态就会被存储,直到有新消息到达,或者直到代码将 saga 标记为已完成并且从存储中删除状态。
如前所述,在 .NET 世界中,MassTransit 和 NServiceBus 支持这一点,但在其他环境中很可能有替代方案。
如果我理解正确,看起来您需要一个 CEP(复杂事件处理器),如ws02 cep或其他,它正是这样做的。当满足某些条件时,cep 可以聚合事件并执行操作。