【问题标题】:How to handle message order in nservicebus?如何处理 nservicebus 中的消息顺序?
【发布时间】:2013-09-11 04:06:36
【问题描述】:

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

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

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

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

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

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

非常感谢一些指导。

谢谢。

【问题讨论】:

    标签: .net msmq nservicebus esb servicebus


    【解决方案1】:

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

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

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

    在您的情况下,可能有更好的方法。鉴于您只想在对订单进行的修订中进行订购。我认为您可以通过一种不需要订购交付的方式来构建它。

    • 将修订号添加到您可以通过修订修改的所有字段
    • 仅当消息中的修订号 >= db 中的最后一个修订时才更新字段

    这有很多好处。

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

    但它有以下缺点:

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

    【讨论】:

    • 在您看来,NServiceBus 为这种场景提供框架级支持有多重要?
    • @UdiDahan 在我们遇到的场景中,我认为我们犯了一个错误,要求订购。如果我不得不再做一次,我会做类似于我上面描述的事情。我认为更好的选择是支持处理程序中的任何顺序,而不是在框架中强制执行顺序,但这只是我的意见。
    • @LukeMcGregor 谢谢 - 我就是这么想的。
    • 感谢您的帮助。我决定使用我的问题中选项 2 的修改版本 - 这样就不依赖于消息顺序。
    • @JoelDSouza 太好了,我真的认为这是正确的方法,尽管实施起来有点困难,但从长远来看,它将为您提供最低的维护方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2016-03-21
    相关资源
    最近更新 更多