简体   繁体   English

如何确保CQRS模式中的消息顺序

[英]How to ensure the order of messages in CQRS pattern

I juggled a bit with Greg Young's sample application and stumbled upon the problem in a multi-threadded environment that the order of messages in a bus might not be guaranteed or the processing of an event might not be completed before the next arrives. 我和Greg Young的示例应用程序有点混淆,并且在多线程环境中偶然发现问题,即总线中的消息顺序可能无法保证,或者事件的处理可能在下一次到达之前未完成。

Because of this, the ItemCreated message might occur after the ItemChangedSomething message, or at least the first message is not processed completely. 因此,ItemCreated消息可能发生在ItemChangedSomething消息之后,或者至少第一条消息未完全处理。 This leads to problems in the "read side", because I want to update data that is not (yet) available. 这导致“读取侧”出现问题,因为我想更新尚未(尚)可用的数据。

How to go around this? 如何解决这个问题? (Assuming CQRS fits for the Domain Design case.) (假设CQRS适合域设计案例。)

Do I have to create a Saga or is there some other way of doing this? 我是否必须创建一个Saga或者还有其他方法吗?

You should choose a messaging infrastructure that guarantees delivery of events in-order on a per-consumer basis, even if multiple threads are delivering in parallel to different consumers. 您应该选择一个消息传递基础结构,以确保按消费者按顺序传递事件,即使多个线程并行传递给不同的消费者。 Ie, if you feed the events in order on the sending side, consumers will receive them in-order. 即,如果您在发送方按顺序提供事件,消费者将按顺序接收它们。

Then there are two basic approaches to handle this situation: 然后有两种基本方法来处理这种情况:

  • Infrastructure : in a small CQRS application without distributed data storage, you can record a global and increasing unique id for each event. 基础设施 :在没有分布式数据存储的小型CQRS应用程序中,您可以为每个事件记录全局且不断增加的唯一ID。 Then make sure events are delivered by the messaging architecture in order of their id. 然后确保事件由消息传递体系结构按其id的顺序传递。 That will completely eliminate out-of-order event delivery. 这将完全消除无序事件传递。 Similarly you can record the time stamp of events and deliver them in order of their time stamp. 同样,您可以记录事件的时间戳,并按照时间戳的顺序交付。 While this might cause race conditions for some cases, for most applications and use cases time stamp based ordering is sufficient (in particular, if ItemCreated and ItemChanged are based on human actions). 虽然这可能会导致某些情况下的竞争条件,但对于大多数应用程序和用例,基于时间戳的排序就足够了(特别是,如果ItemCreatedItemChanged基于人为操作)。

  • State machines : For larger (typically distributed) setups, you can use an explicit or implicit automata/state machine model to cope for out-of-order arrival of messages. 状态机 :对于较大(通常是分布式)的设置,您可以使用显式或隐式自动机/状态机模型来应对消息的无序到达。 With a proper messaging infrastructure, you'll never receive ItemCreated and ItemChanged out of order if they originate from the same stream, but it might happen that events from two different sources (streams/aggregate roots) are consumed by some projection or saga in arbitrary order. 使用适当的消息传递基础结构,如果它们来自同一个流,您将永远不会ItemCreated接收ItemCreatedItemChanged ,但是可能会发生来自两个不同源(流/聚合根)的事件被某些投影或传奇任意使用订购。 Since these events are independent, there usually is a way (think state machine) to keep the projections in a valid state for either order. 由于这些事件是独立的,因此通常有一种方法(想想状态机)将投影保持在任一订单的有效状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM