【问题标题】:MSMQ throws away messages if the destination queue does not exist?如果目标队列不存在,MSMQ 会丢弃消息吗?
【发布时间】:2010-09-23 07:54:56
【问题描述】:

我遇到了一个奇怪的情况:

消息从服务器 A 发送到服务器 B。它进入ServerA的传出队列,然后发送到ServerB的队列。

ServerB 崩溃。我们不得不重新格式化。当我们提起它时,我们忘记安装 MSMQ 服务了。

消息开始在 ServerA 的传出队列中堆积,直到发送消息的程序抛出资源不足异常。

我们注意到错误并将 MSMQ 服务安装到 ServerB 上。 ServerA 开始立即清空其传出队列。

当我们启动程序来处理 ServerB 上的消息时,它无法连接。我们了解到我们忘记在 ServerB 上创建队列。然而,此时,为时已晚。位于 ServerA 队列中的所有 900K 消息都已发送到 ServerB。据我所知,ServerB 把它们扔掉了,因为它没有配置目标队列。我已经知道正确的解决方案是在我们完全设置好 ServerB 之前停止 ServerA 上的队列。

问题是:这真的是我们应该期待的 MSMQ 的真实行为吗?我本以为更防御性的设计方法是让 ServerB 拒绝消息,而不是接受并丢弃它们。

【问题讨论】:

    标签: msmq


    【解决方案1】:

    我们有类似的行为,即消息消失。我注意到,如果“UseDeadLetterQueue”设置为 true,至少在传输失败时,它会在源系统的死信队列中保留一份副本。

    例子:

    var message = new System.Messaging.Message();
    message.UseDeadLetterQueue = true;
    

    【讨论】:

      【解决方案2】:

      当打开队列向远程计算机发送消息时(当 dwAccess 设置为 MQ_SEND_ACCESS 时),消息队列不检查队列是否存在。

      来自 MSMQ 文档:

      http://msdn2.microsoft.com/en-us/library/ms699817.aspx

      原因似乎是 MSMQ 旨在用作异步传输,因此发送方发送,然后在此过程中可能会发生许多不同的事情,导致消息无法传递。 看起来唯一确定的方法是寻找返回的否定确认消息。我们从未使用过这些。 您要么开始使用它们,要么尽量不进行远程发送。

      Usenet thread discussing this.

      【讨论】:

        【解决方案3】:

        这在很大程度上取决于您使用的队列类型以及您要求 MSMQ 对消息采取什么保证。请记住,MSMQ 中的消息在消息传输过程中可能会过期(甚至是读取时间限制)。

        根据您配置发件人的方式,无法传递的消息可能已进入死信队列,因此我肯定会在两台服务器上检查该消息以查看那里的内容。

        如果您想更好地处理这种情况,您可以要求 MSMQ 做更多的事情。例如,您可以要求它在日志队列中保留已发送消息的副本(然后根据需要自己将其排出)。或者,您可以要求它对消息传递或什至正在阅读的消息提供肯定或否定的 ACK。在这些情况下,ACK/NACK 会发送到您选择的管理队列,您自己的应用可以监控和响应该队列。

        【讨论】:

          猜你喜欢
          • 2017-06-29
          • 2017-10-25
          • 2015-10-11
          • 2015-03-17
          • 1970-01-01
          • 2014-10-16
          • 2017-11-11
          • 2010-12-10
          • 2023-02-06
          相关资源
          最近更新 更多