消息队列注意事项 - MSMQ存储问题会导致当前应用程序死亡

时间:2011-07-04 13:25:23

标签: c# .net msmq

我正在开发两个使用MSMQ作为消息总线机制的应用程序,以便A将消息传输到B.这显然必须是健壮的,所以最初我们选择MSMQ来存储和传输消息。

在测试应用程序时,我们注意到在实际情况下,调用msmq每分钟处理大约50.000条消息(对我而言听起来很低),然后我们快速达到msmq / storage目录的最大存储大小(我认为默认为1.2gb。

我们可以增加,但我想知道是否有更好的方法来处理慢接收器和快速发送器。在这种情况下,是否有更好的队列或更好的方法?

实际上它不是一个接收器速度慢的问题,因为msmq会将(收到的)消息保存在存储目录中6个小时或者直到服务重新启动。所以基本上如果在5分钟内我们达到1gb的阈值,那么在几个小时内我们将达到数据的范围!

2 个答案:

答案 0 :(得分:4)

您应该向订阅者申请SLA,他们必须在X时间内阅读他们的消息,否则他们将失去这些消息。您可以缩放此SLA以匹配到达的消息量。

对于那些无法满足他们的SLA然后简单地说,他们并不真正关心快速接收他们的消息(如果他们这样做,他们将可用)。对于这些订阅者,您可以提供较慢的通道,例如过去一小时内消息的XML转储(或者需要的粒度)。您可能不会在此处存储每条消息,而只是存储更改的集合(例如,可以从数据库中查询的内容)。


为每种消息类型使用单独的队列,这样您可以根据消息的重要性应用不同的优先级,如果一个队列已满,则不会阻止其他类型的消息。通过查看队列中的第一条消息并查看何时添加消息以确定它等待的时间(参见NServiceBus),它还可以更简单地监视每条消息是否在其SLA中进行处理。


根据您的上述指标,1分钟,5分钟,50,000条消息/分钟,我计算每封邮件大约4kb。这对于消息来说非常大,因为消息通常应该只包含有关正在发生的事情的顶级详细信息,主要是更改内容的ID以及更改内容的意图。一些其他带外通道可以更好地传输更大的数据,用于传输大型blob(例如,文件共享,sftp等)。

此外,由于服务应封装自己的数据,因此您不需要在服务之间共享大量数据。因此,服务中的大型数据使用消息来说明发生的事情并不罕见,使用消息的单独服务之间的大数据表明某些边界可能正在泄漏。

答案 1 :(得分:4)

请阅读this blog以了解MSMQ如何使用我在Microsoft多年支持MSMQ后整理的资源。
它确实涵盖了您需要了解的所有领域。 如果您已经听说过博客中没有的MSMQ,那么它肯定是错误的 - 例如MSMQ的1.2GB存储限制。 msmq \ storage目录的最大大小是硬盘容量 - 它是一个NTFS文件夹! 您应该能够拥有一个包含数百万条消息的队列(假设您有足够的内核内存,如博客中所述)

干杯
John Breakwell