CQRS 和事件溯源 - 读取您自己的事件

CQRS and Event Sourcing - Read your own events

目前,我正在实施事件驱动架构并有一个命令服务(写入部分)和另一个查询服务(读取部分)。

我现在在做什么。

  1. 在 CommandService 上接受命令
  2. 在事件总线上存储事件和发布事件
  3. ReadService 监听这些事件并更新读取模型

如果你听自己的事件,这听起来不错。 假设我从 CommandService

监听外部事件
  1. 监听事件
  2. 处理此事件的命令
  3. 将您的域生成的事件存储在您的事件存储中并将该事件发布到事件总线
  4. ReadService 监听这些事件并更新读取模型

在这种方法中,我可以看到更新我的读取模型有双重延迟。 第一个延迟 -> CommandService 时间拉事件 第二次延迟 -> ReadService 拉取从 CommandService 生成的事件的时间。

我在想如果我更新我的 ReadService 以直接侦听 CommandService 事件存储而不需要事件总线,那么我可以减少其中一个延迟。

你怎么看?

我们前段时间做过类似的事情。基本上,我们有

  1. 一个服务实现 进程管理器 模式并使用 EventSourcing 和 Saga 在多个服务之间执行一些编排逻辑。存储在数据库中的每个事件都包含一个序列化为 Avro 格式的 EventPayload,其中包含事件发生时的进程状态。该有效负载包含所有状态,而不仅仅是差异,因此我们在处理过程中一直在更新该有效负载。
  2. 我们已经使用 Kafka Connect JDBC Source Connector 从 EventStore 中读取,基本上只要在 EventStore 中发布了新事件,Connector 就会读取该事件并将其发布到 Kafka(Kafka 是用作 EventBus)。
  3. 放置在另一个服务中的读取模型已通过 Kafka 更新(这里有两种方法:使用 Kafka Connect JDBC Sink Connector 或使用 Kafka Consumer 并从 Consumer 进行事务更新)。

希望对您有所帮助!

I'm thinking If I update my ReadService to listen to CommandService eventstore directly without the need of event bus, then I can reduce one of this latency.

是的,你会减少延迟,但你会在两个服务之间引入耦合,这不一定是坏事,但如果两个服务解耦(使用总线),你可以独立地扩展每一个。

此外,如果您使用 RabbitMQ 等托管总线,您将受益于消息确认、多种类型的消息传递和队列等。