7

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

更多细节:

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

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

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

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

处于挂起状态的群集 MSMQ 传出队列

如果我将集群故障转移到另一个节点,就好像整个系统都受到了影响。这是故障转移后不久的同一群集 MSMQ 实例的图片:

故障转移后的群集 MSMQ 传出队列

谁能解释这种行为,以及我能做些什么来避免它,以保持系统平稳运行?

4

3 回答 3

2

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

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

查看这篇博文中的解释和解决方案:链接

于 2010-11-08T19:11:59.900 回答
2

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

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

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

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

我向Udi Dahan(NServiceBus 的作者)询问了这个集群托管策略,他给了我一个不解的表情,问道:“你为什么要做这样的事情?” 实际上,Distributor 非常轻量级,因此实际上没有太多理由将它们均匀地分布在可用节点之间。

在那之后,我们决定利用我们所学到的一切,重新创建一个只有一个 MSMQ 实例的新故障转移集群。从那以后我们就再也没有看到过这个问题。当然,确保这个问题得到解决将被证明是消极的,因此是不可能的。至少 6 个月没有问题,但谁知道呢,我想它明天可能会失败!我们希望不会。

于 2011-12-22T17:37:57.677 回答
1

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

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

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

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

  1. 停止并重新启动所有服务。
  2. 仅停止其中一项服务。
  3. 重新启动停止的服务。
  4. 如果您的系统没有挂起,请对每个服务重复此操作。

如果您的系统现在再次挂起,请检查您的配置。在这种情况下,您至少有一个(如果不是全部)服务会在重新启动之间丢失订阅。如果您还没有这样做,请将订阅保存在数据库中。

于 2010-10-13T15:20:00.047 回答