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

时间:2016-12-13 22:24:57

标签: asynchronous message-queue event-sourcing event-store

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

3 个答案:

答案 0 :(得分:13)

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

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

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

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

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

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

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

答案 1 :(得分:5)

确保您清楚send(命令)和发布(事件)之间的区别。 Udi Dahan在他的busses and brokers文章中谈到了这个话题。

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

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

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

答案 2 :(得分:5)

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

但是他们没有无限期地存储所有消息。您需要有一个活动商店来进行任何类型的活动采购。

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

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

因此,您应该使用KafkaEventStore之类的内容来开箱即用。或者,您可以手动将事件存储与消息队列组合在一起,但这将更加复杂。