我正在使用 Kafka 进行事件溯源,并且我对使用 Kafka 实现 sagas 感兴趣。
有关于如何做到这一点的最佳实践吗? here提到的Commander模式似乎与我正在尝试构建的架构很接近,但演示文稿中的任何地方都没有提到传奇故事。
今年 DDD eXchange 的演讲是我在事件驱动/CQRS 系统中遇到的关于 Process Manager/Saga 模式的最佳资源: https://skillsmatter.com/skillscasts/9853-long-running-processes-in-ddd (需要注册免费帐户才能查看)
展示的演示位于 github 上:https://github.com/flowing/flowing-retail
我已经尝试过它并且非常喜欢它。我建议先观看视频以做好准备。
尽管所示的方法与消息总线无关,但该演示使用 Kafka 作为流程管理器来向其他有界上下文发送命令并侦听来自其他有界上下文的事件。它不使用 Kafka Streams,但我不明白为什么它不能插入 Kafka Streams 拓扑并成为更广泛架构的一部分,就像您引用的 Commander 演示文稿中描述的那样。
我希望根据我们自己的需求进一步调查这一点,所以请随时在 Kafka 用户邮件列表上启动一个线程,这是就此类模式进行协作的好地方。
希望有帮助:-)
我想在这里添加一些关于 Sagas 和 Kafka 的内容。
总的来说,Kafka 与普通队列有点不同。它在缩放方面特别好。这实际上会导致一些并发症。
Kafka 是实现扩展的手段之一,它使用数据流的分区。数据放置在分区中,分区可以按照自己的速率使用,独立于同一主题的其他分区。以下是有关它的一些信息:how-choose-number-topics-partitions-kafka-cluster。我会回来解释为什么这很重要。
确保 Kafka 内顺序的最常见方法是:
在这两种情况下,您的时间相关消息都需要流经同一主题。
此外,正如 @pranjal thakur 指出的那样,请确保传递方法设置为“仅一次”,这会影响性能,但确保您不会多次收到消息。
现在,需要注意的是:更改分区数量时,分区上的消息分布(使用密钥时)也会更改。
在正常情况下,这很容易处理。但是,如果流量较高,则迁移到不同数量的分区可能会导致某个时刻在多个分区上处理传奇“流”,并且此时无法保证顺序。
这是否会成为您的场景中的问题取决于您。
您可以提出一些问题来确定这是否适用于您的系统:
如果您正在考虑建立一个基于步骤的传奇,就像状态机一样,我会要求您重新考虑一下您的设计。
我举个例子:
让我们考虑一下预订酒店房间的流程:
简单来说,可能包括以下步骤:
现在,如果您的传奇在预订尚未到来时无法处理付款,那么您将依赖于事件的顺序。
在这种情况下,你应该问自己:什么时候会崩溃?
如果您认为您想避免时间依赖性;考虑一个没有传奇的系统,或者一个不依赖于事件顺序的传奇 - 即:接受所有消息,即使在这个过程中还没有轮到他们。
一些例子:
请注意,在这样的设置中,更重要的是每个操作都有一个已实施的补偿操作(回滚操作)。
我知道这通常很难实现;但是,如果你从小处开始,你可能会开始喜欢它:-)
在 Rebus.Kafka 上有一个 Saga 的示例!