2016-12-13 58 views
5

我正在使用Java和Cassandra的事件采购从头开始构建项目。 我的应用程序是基于微服务的,在某些使用情况下,信息将被异步处理。我想知道Message Queue(比如Rabbit,Active MQ Artemis,Kafka等)在这个环境中如何改进技术堆栈,以及如果我理解这些场景,我将不会使用它。事件源:何时(而不是)我应该使用Message Queue?

回答

3

请确保您明确了send(command)和publish(event)之间的区别。 Udi Dahan在他的文章busses and brokers上触及了这个话题。

在大多数情况下,你是事件采购,你做而不是想要从发布的事件重建状态。如果你需要状态,然后查询历史记录的技术权威/记录,并从历史中重建状态。

另一方面,事件驱动的活动关闭消息队列应该没问题。当一个事件(加上用户的状态)拥有你需要的一切时,那么逃离总线就没有问题。

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

1

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

但它们不会无限期地存储所有消息。你需要有一个活动商店来做任何事件采购。

的问题不是“排队或者不排队”,但它更像是:

  • 可这件事店内活动的巨大体积无限?
  • 它有发布 - 订阅功能吗?
  • 是否提供至少一次交货保证?

因此,您应该使用类似KafkaEventStore的东西来拥有所有的开箱即用功能。或者,您可以手动将事件存储与消息队列组合起来,但这会涉及更多。

6

我会从像Kafka这样的事件流/存储/处理中分离像RabbitMQ这样的消息传递基础结构。这些是为了两个(或更多)不同目的而做出的两件事情。

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

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

如果查看事件如何持续存在,您可以看到它们作为一个事务保存到商店。如果您需要发布活动,这将是另一个交易。由于您正在处理两种不同的基础设施,因此事情可能会中断。

这样的消息传递问题是消息通常保证“至少传递一次”,并且通常不保证消息的顺序。另外,当你的消息使用者失败并且NACK消息时,它将被重新发送,但通常稍晚一点,再次破坏序列。

排序和复制问题,无论谁,不适用于像Kafka这样的事件流服务器。另外,如果您使用追赶订阅,则EventStore将保证只有一次事件传递顺序。

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

+0

谢谢阿列克谢,在这里的快速问题:“排序和复制问题,谁不适用于像卡夫卡这样的事件流服务器”如何?如果你有并发订阅者,如果这些并发订阅者是相互依赖的,你将不可避免地开始有乱序问题,所以应该根据特定应用的业务规则在他们之间实现一些自定义同步。我的理解是否正确? – IlliakaillI

+0

我个人对Kafka没有经验,但是我观看了关于DDDU 2016的Martin Kleppmann的谈话https://dddeurope.com/2016/martin-kleppmann.html他解释说,当他们设计Kafka时,他们的目标是严格按照事件顺序进行。我也知道EventStore在使用catch/up订阅时保证事件顺序。当您在事件流上设置竞争消费者时,不可避免地会出现此保证,因此您无法在此确保订购。异步处理也会破坏排序。 –

+0

我明白了。我在问,因为在任何高可用性系统中,您必须让竞争的用户具有容错能力,并且看起来像没有机制可以自动处理这种系统的乱序情况。 – IlliakaillI

相关问题