事件采购:何时(而不是)我应该使用Message Queue?

Fel*_*ipe 8 asynchronous message-queue event-sourcing event-store

我正在使用Java和Cassandra的事件采购从头开始构建项目.我的应用程序基于微服务,在某些用例中,信息将以异步方式处理.我想知道Message Queue(例如Rabbit,Active MQ Artemis,Kafka等)将在这个环境中改进技术堆栈的哪个部分,如果我理解这些场景,我将不会使用它.

Ale*_*rev 15

我首先要将像RabbitMQ这样的消息传递基础设施与像Kafka这样的事件流/存储/处理分开.这是为两个(或更多)不同目的而制作的两个不同的东西.

关于活动采购,您必须有一个必须存储活动的地方.此存储必须仅附加,并支持基于标识快速读取非结构化数据.这种持久性的一个例子是EventStore.

事件采购与CQRS一起使用,这意味着您必须将更改(事件)投影到另一个商店,您可以查询.这是通过将事件投影到该存储来完成的,这是处理事件以更改域对象状态的位置.重要的是要理解使用消息基础设施进行预测通常是个坏主意.这是由于消息传递和两阶段提交问题的本质.

如果您查看事件如何持久化,您可以看到它们作为一个事务保存到商店.如果您需要发布事件,这将是另一个事务.由于您使用两种不同的基础设施,因此事情可能会被打破.

这样的消息传递问题是通常保证消息"至少传递一次"并且通常不保证消息的顺序.此外,当您的消息使用者失败并NACK消息时,它将被重新传递,但通常稍后,再次打破序列.

订购和复制问题,无论是谁,都不适用于像Kafka这样的事件流服务器.此外,如果您使用追赶订阅,EventStore将保证只有一次事件交付.

根据我的经验,消息用于发送命令和实现事件驱动的体系结构,以反应方式连接独立服务.另一方面,事件存储用于持久化事件,然后只有到达那里的事件才会被投射到查询存储,并且还会发布到消息总线.


Voi*_*son 5

确保您清楚send(命令)和发布(事件)之间的区别.Udi Dahan在他关于公共汽车和经纪人的文章中谈到了这个话题.

在您进行事件采购的大多数情况下,您希望从已发布的事件重建状态.如果您需要状态,则查询历史记录的技术权限/记录簿,并从历史记录中重建状态.

另一方面,消息队列中的事件驱动活动应该没问题.当一个事件(加上用户的状态)拥有你需要的一切时,那么跑掉公共汽车就可以了.

在某些情况下,您可能会同时做到这两点 例如,如果您要更新缓存视图,则可以订阅各种BobChanged事件以了解缓存数据何时过时; 要重建旧视图,您将重新加载历史记录的表示并将其转换为更新的视图.


Ill*_*llI 5

在事件源应用程序的世界中,消息队列通常允许您在生产者和使用者之间实现发布 - 订阅模式的通信方式.此外,它们通常可以帮助您提供交付保证:哪些消息是传递给哪些订阅者,哪些消息不是.

但它们不会无限期地存储所有消息.您需要有一个活动商店来进行任何类型的活动采购.

问题不是'排队或不排队',而是更像是:

  • 这件事可以无限期地存储大量的事件吗?
  • 它有发布 - 订阅功能吗?
  • 它是否提供至少一次交付保证?

所以,你应该使用像KafkaEventStore这样的东西来开箱即用.或者,您可以手动将事件存储与消息队列组合,但这将更加复杂.