4

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

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

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

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

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

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

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

4

3 回答 3

2

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

从 MSMQ 文档:

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

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

Usenet线程讨论这个。

于 2009-02-13T16:23:53.147 回答
1

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

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

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

于 2008-11-21T01:03:53.483 回答
0

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

例子:

var message = new System.Messaging.Message();
message.UseDeadLetterQueue = true;
于 2013-09-17T16:01:56.600 回答