【问题标题】:MSMQ messages bound for clustered MSMQ instance get stuck in outgoing queues发往群集 MSMQ 实例的 MSMQ 消息卡在传出队列中
【发布时间】:2011-04-21 22:20:19
【问题描述】:

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

更多细节:

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

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

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

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

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

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

【问题讨论】:

  • 从节点最终会挂掉吗?工人们的表现如何?他们是否在积极处理消息?
  • 这种情况并不经常发生,我可以权威地说它只发生在一个节点或两个节点上。工作人员正在表现 - 当他们的本地输入队列中有消息要处理时,他们正在积极处理消息。
  • 很奇怪。它多久发生一次?每个节点有多少个网卡?我想知道 MSMQ 是否对使用哪张卡感到困惑,因此偶尔不会完成回复。应该有一个注册表设置来锁定它。
  • 每周可能发生 2-3 次。所有涉及的服务器(集群节点和工作节点)都在 VSphere 上进行了虚拟化。每个集群节点都位于不同主机上的 VSphere 来宾上。在他们的虚拟配置中,每台服务器只有一个 NIC 卡。当然,使用集群服务时,会有多个 IP 地址跳来跳去。
  • 你有没有想过这个问题?就好像有什么东西正在把节点从分发器那里拿走。

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


【解决方案1】:

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

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

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

【讨论】:

  • 这不是我的情况,但非常好的信息。而且,似乎与 MSMQ 的课程一样,隐藏得很好。希望它会帮助别人。另一方面,我会继续寻找......
【解决方案2】:

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

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

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

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

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

在那之后,我们决定把我们学到的所有东西和recreate a new Failover Cluster with only one MSMQ instance。从那以后我们就再也没有看到过这个问题。当然,确保这个问题得到解决将被证明是消极的,因此是不可能的。至少 6 个月没有问题,但谁知道呢,我想它明天可能会失败!希望不会。

【讨论】:

    【解决方案3】:

    您的端点是如何配置为持久订阅的?

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

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

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

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

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

    【讨论】:

    • 订阅已保存在共享数据库中。群集分发服务器将其状态存储在群集 MSMQ 队列中。如果一个 worker 被故障转移集群管理器重新启动,它首先要做的事情之一(在任何启动时)就是发送 ReadyMessage。
    • 工人在启动时发送ReadyMessage是真的。我要求持久订阅,因为我遇到了类似的问题。其中一个订阅未正确保存在数据库中,因此在重新启动后,虽然它发送了消息,但其他订阅完全忽略了它,因为他们只检查了数据库。唯一的例外是当所有服务一起重新启动时,然后再次收到相关服务的消息。服务重启时:消息再次失败。
    猜你喜欢
    • 2011-05-01
    • 2012-01-19
    • 2011-01-08
    • 2012-02-12
    • 2012-03-27
    • 2011-06-02
    • 2017-04-27
    • 2018-02-20
    • 2016-04-17
    相关资源
    最近更新 更多