我正在使用Java和Cassandra的事件采购从头开始构建项目。 我的应用程序基于微服务,在某些用例中,信息将以异步方式处理。我想知道Message Queue(例如Rabbit,Active MQ Artemis,Kafka等)在这个环境中会改进技术堆栈的部分,如果我理解这些情况,我会不会使用它。
答案 0 :(得分:13)
我首先将像RabbitMQ这样的消息传递基础设施与像Kafka这样的事件流/存储/处理分开。这是为两个(或更多)不同目的而制作的两个不同的东西。
关于活动采购,您必须有一个必须存储活动的地方。此存储必须仅附加,并支持基于标识快速读取非结构化数据。这种持久性的一个例子是EventStore。
事件采购与CQRS结合在一起,这意味着您必须将更改(事件)投影到另一个商店,您可以查询。这是通过将事件投影到该存储来完成的,这是处理事件以更改域对象状态的位置。重要的是要理解使用消息基础设施进行预测通常是个坏主意。这是由于消息传递和两阶段提交问题的性质。
如果您查看事件如何持久化,您可以看到它们作为一个事务保存到商店。如果您需要发布事件,这将是另一个事务。由于你使用两种不同的基础设施,事情就会崩溃。
这样的消息传递问题是通常保证消息能够被传送至少一次#34;并且通常不保证消息的顺序。此外,当您的消息使用者失败并且消息消息时,它将被重新传递,但通常稍后,再次打破序列。
订购和复制问题,无论是谁,都不适用于像Kafka这样的事件流服务器。此外,如果您使用追赶订阅,EventStore将保证只有一次事件交付。
根据我的经验,消息用于发送命令和实现事件驱动的体系结构,以反应方式连接独立服务。另一方面,事件存储用于保存事件,只有到达事件的事件才会被投射到查询存储,并且还会发布到消息总线。
答案 1 :(得分:5)
确保您清楚send(命令)和发布(事件)之间的区别。 Udi Dahan在他的busses and brokers文章中谈到了这个话题。
在您进行事件采购的大多数情况下,不希望从已发布的事件中重建状态。如果您需要状态,则查询历史记录的技术权限/记录簿,并从历史记录中重建状态。
另一方面,消息队列中的事件驱动活动应该没问题。当一个单一的事件(加上用户的状态)拥有你需要的一切时,那么跑掉公共汽车就可以了。
在某些情况下,您可以同时执行这两项操作。例如,如果您要更新缓存的视图,则可以订阅各种BobChanged
事件,以了解缓存数据何时过时;要重建陈旧的视图,您将重新加载历史记录的表示并将其转换为更新的视图。
答案 2 :(得分:5)
在事件源应用程序的世界中,消息队列通常允许您在生产者和使用者之间实现发布 - 订阅模式的通信方式。此外,他们通常会帮助您提供交付保证:哪些消息是发送给哪些订阅者,哪些消息不是。
但是他们没有无限期地存储所有消息。您需要有一个活动商店来进行任何类型的活动采购。
问题不是'排队或不排队',而是更像是:
因此,您应该使用Kafka或EventStore之类的内容来开箱即用。或者,您可以手动将事件存储与消息队列组合在一起,但这将更加复杂。