.net - 如何处理 nservicebus 中的消息顺序?

标签 .net msmq nservicebus esb servicebus

我正在尝试找到一种方法来按照从发件人发送的顺序处理消息,因为 NServiceBus 不保证消息将按特定顺序处理。

发送方是一个订单系统,它发布createOrder 和reviseOrder 命令。发件人允许用户对同一订单提交多个修订,因此队列中可以同时有修订 4 和修订 3。每个修订版都有一个修订号和与之关联的原因代码,它驱动一些业务逻辑,因此我们不能忽略任何修订或至少是它的原因部分。

下面列出了我的一些想法 -

  1. 将修订号与目标记录一起存储。发件人在每个修订消息中发送他们的修订号。处理程序比较发件人和目标修订号,如果它们匹配,则更新记录,否则将消息放在队列的末尾。使用这种方法,如果修订 2 消息失败并进入错误队列,则永远不会处理修订 3。

  2. 发件人在每条修订消息上发送所有修订的所有原因代码的历史记录。因此,如果修订 2 消息失败,修订 3 消息将具有所有原因代码。这些原因代码将记录在目标中,但可能不会出现与先前修订原因代码相关的任何业务逻辑。

我们如何针对这种场景进行设计?
还有关于如何处理失败的修订消息的任何想法?

非常感谢一些指导。

谢谢。

最佳答案

关于 NserviceBus 的开箱即用的主要准则之一是您应该以一种顺序无关紧要的方式构建您的系统。话虽如此,我之前已经使用 NSB 构建了一个有序系统,但我决定这样做:

  • 为所有消息添加序列号
  • 在接收器中检查序列号是最后看到的数字 + 1 如果没有抛出乱序异常
  • 启用二级重试(因此,如果它们出现故障,它们会希望在收到正确的消息后重试)

这通常工作得很好,但有时如果某些东西出现故障时间过长并且需要手动干预以重新排序,那么东西会有点不正常。

在您的场景中,可能有更好的方法。鉴于您只想在对订单所做的修订中进行订购。我认为您可以以不需要订购交付的方式构建它。

  • 将修订号添加到您可以使用修订修改的所有字段
  • 仅当消息中的修订号 >= 数据库中的最后修订时才更新字段

这有很多好处。

  • 它不依赖于顺序
  • 它通过只要求接收方处理每条消息一次来减少负载
  • 如果一条消息出现问题,它不会停止一切,从而很好地处理错误。

但它有以下缺点:

  • 增加数据库的复杂性
  • 它最终是一致的,如果您查看数据库,它可能只包含用户所做的一些编辑。
  • 如果 rev2 错误并且 rev3 被正确处理,一些用户编辑将不会存在,但有些会存在

关于.net - 如何处理 nservicebus 中的消息顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18668233/

相关文章:

c# - 更新面板触发器 : Could not find an event named 'OnRowCommand'

.net - 我可以使用 EF Code First 和 .net core 生成迁移脚本吗

c# - 如何检查公共(public)MSMQ是否为空

NserviceBus - NHibernate.StaleStateException : Batch update returned unexpected row count from update; actual row count: -1; expected: 1

c# - 在不复制源列表的情况下高效地对 IList<T> 进行排序

c# - SendGrid 无法从传输连接读取数据 : net_io_connectionclosed

c# - MSMQ 一个(队列)到多个(监听器)场景

.net - WCF MSMQ使用者线程数

NServiceBus 动态端点