NServiceBus - 如何在不同的线程/进程上发生Bus.Send()时控制消息处理程序的排序?

时间:2012-01-10 13:58:45

标签: nservicebus

情景:

我有一个通过NServiceBus发送审核消息的方案。处理程序在预先存在的数据库表上插入和更新一行,我们无需更改。要求是我们可以控制消息的处理顺序,以便审计数据反映正确的系统状态。无序处理的消息可能导致审计数据反映不正确的状态。

某些审核数据是按特定顺序预期的,但有些可以在初始消息之后的任何时间接收,例如状态更新,将在此过程中多次发送。

在我的测试项目中,我一直在测试使用服务器(特别是ISpecifyMessageHandlerOrdering功能),其终点配置如下:

public class MyServer : IConfigureThisEndpoint, AsA_Server, ISpecifyMessageHandlerOrdering
    {
          public void SpecifyOrder(Order order)
          {
               order.Specify(First<PrimaryCommand>.Then<SecondaryCommand>());
          }
    }

由于消息的显式顺序未知,因此一条消息InitialAuditMessage是初始消息,并且继承自PrimaryCommand。

稍后允许接收的其他消息继承自SecondaryCommand。

public class StartAuditMessage : PrimaryCommand
public class UpdateAudit1Message : SecondaryCommand
public class UpdateAudit2Message : SecondaryCommand
public class ProcessUpdateMessage : SecondaryCommand

这可以控制从同一个线程发送消息的处理顺序。

但是,如果消息是从不同的线程或进程发送的,那么这就会失败,这是有道理的,因为没有什么可以将消息链接为相关的。

如何通过某种ID来链接消息,以便在从单独的线程发送时不会无序处理它们?这是Sagas的用例吗?

此外,关于状态更新消息,我如何确保按照发送顺序处理相同类型的消息?

1 个答案:

答案 0 :(得分:1)

每当您需要订购处理时,您无法避免在处理过程中的某些时候需要将所有内容限制为单个线程的结论。单线程保证处理事物的顺序。

在某些情况下,您可以通过使用关联标识符拆分处理,将单个线程“扩展”为多个线程。相关ID允许您定义必须维护顺序的消息的逻辑分组。这允许您使每个执行有序处理的并发线程更有效。