我们已经为一组NServiceBus服务聚集了MSMQ,一切都运行良好,直到它没有 . 一台服务器上的传出队列开始填满,很快整个系统都挂起了 .
更多细节:
我们在服务器N1和N2之间有一个集群MSMQ . 其他群集资源只是作为本地(即NServiceBus分发服务器)直接在群集队列上运行的服务 .
所有工作进程都位于不同的服务器上,即Services3和Services4 .
对于那些不熟悉NServiceBus的人来说,工作会进入由经销商管理的集群工作队列 . Service3和Services4上的工作程序应用程序将“我准备工作”消息发送到由同一分发服务器管理的集群控制队列,并且分发服务器通过将一个工作单元发送到工作进程的输入队列来响应 .
在某些时候,这个过程可以完全挂起 . 下面是系统挂起时集群MSMQ实例上的传出队列的图片:
如果我将群集故障转移到另一个节点,就像整个系统在裤子中得到了一些好处 . 以下是故障转移后不久的同一群集MSMQ实例的图片:
任何人都可以解释这种行为,以及我可以做些什么来避免它,以保持系统平稳运行?
3 回答
也许您的服务器已克隆,因此共享相同的队列管理器ID(QMId) .
MSMQ使用QMId作为缓存来缓存远程机器的地址 . 如果您的网络中有多台计算机具有相同的QMId,则最终可能会出现卡住或丢失的消息 .
查看此博客文章中的解释和解决方案:http://blogs.msdn.com/b/johnbreakwell/archive/2007/02/06/msmq-prefers-to-be-unique.aspx
一年后,似乎我们的问题已得到解决 . 关键要点似乎是:
确保您拥有可靠的DNS系统,因此当MSMQ需要解析主机时,它可以 .
仅在Windows故障转移群集上创建一个MSMQ的群集实例 .
当我们设置Windows故障转移群集时,我们假设在非活动节点上“浪费”资源是不好的,因此,当时有两个准相关的NServiceBus集群,我们为Project1创建了一个集群MSMQ实例,以及Project2的另一个集群MSMQ实例 . 大多数情况下,我们认为,我们会在不同的节点上运行它们,并且在维护窗口期间,它们将共同定位在同一节点上 . 毕竟,这是我们对SQL Server 2008的主要和开发实例的设置,并且一直运行良好 .
在某些时候,我开始对这种方法产生怀疑,特别是因为在每个MSMQ实例上失败一次或两次似乎总是让消息再次移动 .
我问了这个集群主机策略Udi Dahan(NServiceBus的作者),他给了我一个疑惑的表达并问了"Why would you want to do something like that?"实际上,分配器非常轻量级,所以没有太多理由在可用节点之间均匀分配它们 .
在那之后,我们决定采取我们学到的所有东西和recreate a new Failover Cluster with only one MSMQ instance . 从那以后我们还没有看到这个问题 . 当然,确保这个问题得到解决将证明是消极的,因而是不可能的 . 它没有希望不是.2668959的希望不是 .
如何配置 endpoints 以保留其订阅?
如果一个(或多个)服务遇到错误并由Failoverclustermanager重新启动,该怎么办?在这种情况下,此服务将永远不会再从其他服务收到“我准备工作”消息之一 .
当你故障转移到另一个节点时,我猜你所有的服务都会再次发送这些消息,结果一切都恢复正常 .
要测试此行为,请执行以下操作 .
停止并重新启动所有服务 .
仅停止其中一项服务 .
重新启动已停止的服务 .
如果您的系统没有挂起,请对每个服务重复此操作 .
如果您的系统现在再次挂起,请检查您的配置 . 在这种情况下,您的至少一个(如果不是全部)服务会在重新启动之间丢失订阅 . 如果您尚未执行此操作,请将订阅保留在数据库中 .