我们正在开发一个应用程序,它将通过消息队列(Azure)从各种系统接收事件,但有些事件(消息)可能不会按照它们发送的顺序到达。这些事件将由基于CQRS / ES的中央系统接收和处理,但我担心如果事件以错误的顺序放入事件存储中,我们将得到垃圾(例如“添加订单项后”的“订单创建”) “)。
典型的ES系统是否意味着解决此问题,还是我们打算确保在推入事件存储之前将这些消息按正确的顺序排列?如果您有链接到备份任一视图的文章,那将有所帮助。
编辑:我认为我的描述显然过于模糊,所以回复虽然有助于理解CQRS / ES,但并没有完全回答我的问题所以我会添加更多细节,希望有人会认识到这个问题。 / p>
首先是球员。
将仓库链接到管理系统是一种相当薄的基于Azure云的耦合。来自仓库的消息被发送到云中的WCF / Soap层,解析并通过消息总线发送。通过消息总线发送到仓库的消息,然后再次在云中,将Soap调用转换为仓库中的服务器。
仓库非常小心,以确保它发送的消息具有无间隙递增的标识符,以便我们知道何时错过消息。然而,当我们接收这些消息并将它们转发到管理系统时,它们通过消息总线传输,理论上可能以错误的顺序到达。
现在假设消息中有序列号,我们可以确保消息在发送到CQRS / ES系统之前以正确的顺序放回,但我的问题是,是否必要,ES实际上是否可以用于将事件重新排序为他们想要的逻辑顺序?
答案 0 :(得分:1)
到达服务总线的每条消息都标有SequenceNumber。 SequenceNumber是一个单调递增的无间隙64位整数序列,其范围限定为Queue(或Topic),它通过到达队列提供绝对订单标准。由于错误/中止而该订单可能与交货订单不同,因此您可以重新组合到货订单。
Service Bus中用于管理队列内部订单的两个功能是:
这些功能专为Office 365中的文档工作流而构建,其中顺序显然非常重要。
答案 1 :(得分:1)
我会对KarlM的答案发表评论但是stackoverflow不会允许它,所以这里有...
听起来您希望传输机制在聚合上提供事务锁定。对我来说这听起来本身就是错误的。
听起来好像提出的设计存在缺陷。在过去遇到这个问题时,我会看看你的约束。您要么为网站提供交易保证,要么想要将它们提供给仓库。你不能两者都做,总是赢。
完全分发:如果您想将它们提供给网站,那么仓库必须询问它是否可以开始履行订单。如果您想将它们提供给仓库,那么网站必须询问是否可以取消订单。
希望这很有用。
答案 2 :(得分:0)
对于从"乐观锁定中的单个命令处理程序/聚合生成的事件"方案,我假设您将在事件中包含聚合版本,因此这些事件是隐式排序的。
来自多个聚合的事件不应该关心订单,因为聚合的事务保证。
查看http://cqrs.nu/Faq/aggregates,http://cqrs.nu/Faq/command-handlers及相关常见问题解答
有关ES和乐观锁定的介绍,请查看http://www.jayway.com/2013/03/08/aggregates-event-sourcing-distilled/
答案 3 :(得分:0)
你说: “这些事件将由基于CQRS / ES的中央系统接收和处理,但我担心的是,如果事件以错误的顺序放入事件存储中,我们将被垃圾输出(例如”添加订单后“订单创建”项目”)。” 关于事件采购的CQRS模式似乎存在误解。 简单地说,事件源是指您通过内部生成的事件更改聚合(根据DDD术语),聚合持久性由事件表示,聚合可以通过重放事件来恢复。这意味着范围非常小,即Aggregate本身。 现在,具有事件源的CQRS意味着来自聚合的这些事件被发布并用于创建读取投影或具有不同目的的其他域模型。 鉴于上述解释,我并没有真正得到你的问题。
与订购相关:
答案 4 :(得分:0)
MSDN https://msdn.microsoft.com/en-us/library/jj591559.aspx上的文章指出“存储事件应该是不可变的,并且始终按照”性能,可伸缩性和一致性“中的保存顺序读取。这显然意味着不能容忍无序附加事件。同一篇文章还多次声明,虽然事件无法改变,但可以进行纠正事件。这将再次暗示事件按接收顺序处理以确定当前事实(聚合的状态)。我的结论是,我们应该在将事件发布到事件存储之前修复消息传递顺序问题。