代码之家  ›  专栏  ›  技术社区  ›  Phil Sandler

从队列中选择性地读取—自定义MSMQ服务、ESB或其他什么?

  •  2
  • Phil Sandler  · 技术社区  · 14 年前

    寻找一些想法/模式来解决一个系统的设计问题,我将很快开始工作。毫无疑问,我将需要使用某种消息传递(可能是MSMQ)在系统的某些区域之间进行通信。我不想重新发明轮子,但同时我想确保我使用的是正确的工作工具。我一直在修补和阅读NServiceBus,它的功能给我留下了深刻的印象——但是我不确定它是否是我想要实现的目标。

    以下是(希望)非常简单和概念性的描述,说明系统需要做什么:

    我有一个客户可以发送信息的服务。该服务是“Fire and Forget”--客户机得到的最多的信息可能是success或failure(成功是收到消息)。

    每个消息的处理/处理都非常重要,可能会占用大量的系统资源。因此,只能并发处理X条消息,其中X是一个可配置的值(基于系统规范等)。传入的消息将存储在队列中,直到“轮到他们”处理为止。

    对于每个客户机,必须按顺序处理消息(FIFO)。但是,有些客户端可能会连续发送许多消息(数千条或更多),例如,如果它们在一段时间内失去了连接。因此,必须以循环方式跨客户端处理消息——不允许任何客户端吞咽消息,也不允许任何客户端饿死消息。因此,系统必须能够查询特定客户机的队列,或者为每个客户机创建单独的队列(自动地,因为客户机在编译时是未知的)并轮流从中提取。

    ESB是否是该作业的错误工具?有没有其他技术或模式我应该看看?

    更新

    一些澄清。

    我相信这在vanilla MSMQ中通常是可能的——您可以在一个队列中有一个消息列表,并且总是先获取最早的消息。

    我还想阐明循环排序的一个用例。在本例中,我有两个发送消息的客户机(A和B),只有一个工作线程。所有队列都是空的。客户端A一夜之间失去了连接,因此在上午8点向服务发送1000条消息。这些消息进入队列,工作线程接收最早的消息并开始处理它。在处理第一条消息时,客户机B向服务发送一条消息,服务排队(如前所述,可能在一个单独的队列中)。当客户机A的第一条消息完成处理时,逻辑应该检查客户机B是否有一条消息(这是客户机B的“轮到”),既然它找到了一条消息,接下来就处理它。

    如果客户机B在此期间没有发送消息,工作进程将继续一次一条地处理客户机a的消息,总是在处理后检查其他客户机队列是否包含等待消息,以确保没有客户机被饿死。

    我仍然觉得ESB和这个问题之间可能存在不匹配的地方是ESB被设计成促进服务之间的通信;我试图实现的是消息传递/通信和选择性排队系统的组合。

    2 回复  |  直到 14 年前
        1
  •  2
  •   John Breakwell    14 年前

    能够查询特定客户机的队列,

    使用游标在MSMQ队列中搜索来自特定客户机的消息可能效率低下,而且无法扩展。

    客户机在编译时是未知的)并轮流从中提取。

    MSMQ无法自动创建队列。所有消息必须先发送到已知队列。不过,您自己的定制调度服务可以根据需要创建新队列,并将消息的副本放入队列中。

    [[我避免说“move”消息,因为您不能用应用程序代码执行此操作;您只能读取消息并使用原始数据创建新消息。例如,在使用源日志记录时,这种区别非常重要。]]

    干杯

    约翰·布雷克韦尔

        2
  •  2
  •   Mikael Koskinen    14 年前

    使用像NServiceBus这样的ESB似乎是解决问题的好方法。但是根据你的概念描述,有一些事情要考虑。让我们使用NServiceBus作为可能的ESB解决方案,一步一步地了解您的需求:

    使用NServiceBus很容易做到这一点。你可以公车。发送(信息)来自客户。如果您的客户需要答案,您可以使用巴士。返回(错误代码)。你提到“成功在于收到了信息”。如果您使用像NServiceBus这样的ESB, it's up to the messaging platform the deliver the message . 所以,如果你的公车。发送如果不引发异常,则可以确保消息已正确发送。因此,您可能不必将成功/失败消息发送回客户端。

    每个消息的处理/处理都非常重要,可能会占用大量的系统资源。因此,只能并发处理X条消息,其中X是一个可配置的值(基于系统规范等)。传入的消息将存储在队列中,直到“轮到他们”处理为止。

    使用NServiceBus时,可以通过设置“NumberOfWorkerThreads”选项来配置工作线程的数量。如果您的服务器有多个核心/cpu,则可以使用此设置来平衡工作负载。

    根据您的要求,这可能会导致问题。ESB一般不承诺处理 the messages in-order ,如果它们有许多线程处理消息。在NServiceBus的情况下,您可以将一组消息从客户机发送到总线并 these will be processed in-order. 此外,还可以通过使用 Sagas .

    但是,有些客户端可能会连续发送许多消息(数千条或更多),例如,如果它们在一段时间内失去了连接

    当使用ESB解决方案时,您的服务器不必为客户机工作。客户端仍然可以发送消息,服务器将在恢复联机后立即开始处理这些消息。这里有一个 small introduction on this.

    你能详细介绍一下吗?我不确定你的设计。