CQRS模式如何保证消息的顺序
How to ensure the order of messages in CQRS pattern
我玩弄了一下 Greg Young's sample application 并偶然发现了多线程环境中的问题,即总线中消息的顺序可能无法保证,或者事件的处理可能无法在下一个到了。
因此,ItemCreated 消息可能发生在 ItemChangedSomething 消息之后,或者至少第一条消息未被完全处理。这会导致 "read side" 出现问题,因为我想更新(尚未)可用的数据。
如何解决这个问题? (假设 CQRS 适合域设计案例。)
我必须创建一个 Saga 还是有其他方法可以做到这一点?
您应该选择一种消息传递基础结构,以保证在每个消费者的基础上按顺序传递事件,即使多个线程并行传递给不同的消费者也是如此。即,如果您在发送端按顺序提供事件,消费者将按顺序接收它们。
那么有两种处理这种情况的基本方法:
Infrastructure:在没有分布式数据存储的小型CQRS应用中,可以为每个事件记录一个全局递增的唯一id。然后确保事件由消息传递体系结构按照它们的 id 的顺序传递。这将完全消除乱序事件传递。同样,您可以记录事件的时间戳并按照时间戳的顺序传送它们。虽然这可能会在某些情况下导致竞争条件,但对于大多数应用程序和用例来说,基于时间戳的排序就足够了(特别是,如果 ItemCreated
和 ItemChanged
是基于人为操作的)。
状态机:对于较大的(通常是分布式的)设置,您可以使用显式或隐式 automata/state 机器模型来应对输出消息的顺序到达。使用适当的消息传递基础设施,如果 ItemCreated
和 ItemChanged
来自同一流,您将永远不会乱序接收它们,但可能会发生来自两个不同来源的事件(streams/aggregate 根) 以任意顺序被某些投影或传奇消耗。由于这些事件是独立的,因此通常有一种方法(想想状态机)可以使任一顺序的投影保持有效状态。
我玩弄了一下 Greg Young's sample application 并偶然发现了多线程环境中的问题,即总线中消息的顺序可能无法保证,或者事件的处理可能无法在下一个到了。
因此,ItemCreated 消息可能发生在 ItemChangedSomething 消息之后,或者至少第一条消息未被完全处理。这会导致 "read side" 出现问题,因为我想更新(尚未)可用的数据。
如何解决这个问题? (假设 CQRS 适合域设计案例。)
我必须创建一个 Saga 还是有其他方法可以做到这一点?
您应该选择一种消息传递基础结构,以保证在每个消费者的基础上按顺序传递事件,即使多个线程并行传递给不同的消费者也是如此。即,如果您在发送端按顺序提供事件,消费者将按顺序接收它们。
那么有两种处理这种情况的基本方法:
Infrastructure:在没有分布式数据存储的小型CQRS应用中,可以为每个事件记录一个全局递增的唯一id。然后确保事件由消息传递体系结构按照它们的 id 的顺序传递。这将完全消除乱序事件传递。同样,您可以记录事件的时间戳并按照时间戳的顺序传送它们。虽然这可能会在某些情况下导致竞争条件,但对于大多数应用程序和用例来说,基于时间戳的排序就足够了(特别是,如果
ItemCreated
和ItemChanged
是基于人为操作的)。状态机:对于较大的(通常是分布式的)设置,您可以使用显式或隐式 automata/state 机器模型来应对输出消息的顺序到达。使用适当的消息传递基础设施,如果
ItemCreated
和ItemChanged
来自同一流,您将永远不会乱序接收它们,但可能会发生来自两个不同来源的事件(streams/aggregate 根) 以任意顺序被某些投影或传奇消耗。由于这些事件是独立的,因此通常有一种方法(想想状态机)可以使任一顺序的投影保持有效状态。