绑定到群集MSMQ实例的MSMQ消息卡在传出队列中

时间:2010-10-06 16:03:04

标签: msmq message-queue nservicebus cluster-computing msdtc

我们为一组NServiceBus服务集群MSMQ,一切都运行良好,直到它没有。一台服务器上的传出队列开始填满,很快就会挂起整个系统。

更多详情:

我们在服务器N1和N2之间有一个集群MSMQ。其他群集资源只是作为本地(即NServiceBus分发服务器)直接在群集队列上运行的服务。

所有工作进程都位于不同的服务器上,即Services3和Services4。

对于那些不熟悉NServiceBus的人来说,工作会进入由经销商管理的集群工作队列。 Service3和Services4上的工作程序应用程序将“我准备工作”消息发送到由同一分发服务器管理的集群控制队列,并且分发服务器通过将一个工作单元发送到工作进程的输入队列来响应。

在某些时候,这个过程可以完全挂起。下面是系统挂起时群集MSMQ实例上的传出队列的图片:

Clustered MSMQ Outgoing Queues in Hung State

如果我将群集故障转移到另一个节点,就像整个系统在裤子中得到了一些好处。以下是故障转移后不久的同一群集MSMQ实例的图片:

Clustered MSMQ Outgoing Queues After Failover

任何人都可以解释这种行为,以及我可以做些什么来避免它,以保持系统顺利运行?

3 个答案:

答案 0 :(得分:2)

也许您的服务器已克隆,因此共享相同的队列管理器ID(QMId)。

MSMQ使用QMId作为缓存来缓存远程机器的地址。如果您的网络中有多台计算机具有相同的QMId,则最终可能会出现卡住或丢失的消息。

查看此博文中的解释和解决方案:http://blogs.msdn.com/b/johnbreakwell/archive/2007/02/06/msmq-prefers-to-be-unique.aspx

答案 1 :(得分:2)

一年后,我们的问题似乎已经解决了。关键要点似乎是:

  • 确保您拥有可靠的DNS系统,因此当MSMQ需要解析主机时,它可以。
  • 仅在Windows故障转移群集上创建一个MSMQ群集实例。

当我们设置Windows故障转移群集时,我们假设在非活动节点上“浪费”资源是不好的,因此,当时有两个准相关的NServiceBus群集,我们制作了一个群集MSMQ Project1的实例,以及Project2的另一个集群MSMQ实例。大多数情况下,我们认为,我们会在不同的节点上运行它们,并且在维护窗口期间,它们将共同定位在同一节点上。毕竟,这是我们对SQL Server 2008的主要和开发实例的设置,并且一直运行良好。

在某些时候,我开始对这种方法产生怀疑,特别是因为对每个MSMQ实例进行一次或两次失败似乎总是让消息再次移动。

我问Udi Dahan(NServiceBus的作者)有关这种集群托管策略的问题,他给了我一个疑惑的表情,问道:“你为什么要这样做呢?”实际上,分发服务器非常轻量级,因此没有太多理由在可用节点之间均匀分配它们。

在那之后,我们决定采取我们学到的所有内容和recreate a new Failover Cluster with only one MSMQ instance。从那以后我们还没有看到这个问题。当然,确保这个问题得到解决将证明是消极的,因而是不可能的。这至少6个月都没有问题,但谁知道,我想明天可能会失败!我们希望不会。

答案 2 :(得分:1)

您的终端如何配置为保留其订阅?

如果一个(或多个)服务遇到错误并由Failoverclustermanager重新启动,该怎么办?在这种情况下,此服务将永远不会再从其他服务收到“我准备工作”消息之一。

当你故障转移到另一个节点时,我猜你所有的服务都会再次发送这些消息,结果一切都恢复了工作。

要测试此行为,请执行以下操作。

  1. 停止并重新启动所有服务。
  2. 只停止其中一项服务。
  3. 重新启动已停止的服务。
  4. 如果您的系统没有挂起,请对每项服务重复此操作。
  5. 如果您的系统现在再次挂起,请检查您的配置。在这种情况下,您的至少一个(如果不是全部)服务会在重新启动之间丢失订阅。如果您尚未这样做,请将订阅保留在数据库中。