【问题标题】:How to increase number of messages that can be stored in MSMQ如何增加可以存储在 MSMQ 中的消息数量
【发布时间】:2011-12-25 14:57:45
【问题描述】:

我们的系统中有许多 MSMQ 队列,包括私有队列和公共队列。有时,从队列中读取的 Windows 服务会崩溃,因此消息会在该队列中堆积。一旦队列达到一定大小(可能是 60K 消息),该服务器上的所有队列都将停止工作,并抛出有关资源不足的错误。

我的问题是,队列在幕后是如何真正工作的,它们是将消息存储在 RAM 中还是硬盘上?当服务器内存不足时,它是否会耗尽资源并崩溃?如果它正在使用硬盘驱动器上的一些分配空间,有没有办法增加允许的大小?如果它使用 RAM,我可以简单地向服务器添加 RAM,然后增加允许的大小吗?

我需要确保当服务出现故障时,我们可以在修复服务时处理在该队列中存储 100K 或 200K 消息,因为这些消息对我们的业务至关重要。

【问题讨论】:

  • 60,000 条消息是一个微不足道的数量,因此在您开始之前,您的服务器必须已经非常低的内核内存。添加 RAM 无济于事,因为大多数现代机器都配备了足够的 RAM 来最大化内核内存。您需要识别并移除内核内存占用。配置良好的机器可以处理数百万条消息。

标签: msmq msmq-wcf


【解决方案1】:

不确定深入的答案,但无论如何从表面上看,非事务队列将消息存储在内存中,而事务队列将消息存储在磁盘上。

更新

正如 John 在下面所述,无论使用持久队列还是非持久队列,所有消息都保存在磁盘上。

【讨论】:

  • 这是不正确的。所有消息都写入磁盘。事务性和可恢复消息以这样的方式写入磁盘,以便在重新启动后可以恢复。重新启动后,Express 消息会丢失。 blogs.msdn.com/b/johnbreakwell/archive/2008/04/04/…
  • 谢谢约翰。这似乎是不直观的,但我当然相信你的产品背景。
  • 是的,确实如此。在一位最初的建筑师纠正我之前,我多年来一直在告诉人们错误的事情。
【解决方案2】:

这是 MSDN 上的一篇文章,似乎解决了您的问题(正如 John 在下面指出的,这仅适用于 Windows Server 2000,因此大多数人可能应该忽略):Resource management in MSMQ applications。具体来说:

对于 MSMQ 1.0 和 MSMQ 2.0,可以在一台机器上存储的消息的组合大小不受机器内存量或硬盘大小的限制,而是提供的虚拟地址空间量由操作系统发送到 MSMQ 服务(此限制已在 MSMQ 3.0 中解除)。 x86 机器中的每个进程都分配有一个虚拟的 4 GB 可寻址内存。 2GB 保留用于内核模式,2GB 用于用户模式。 MSMQ 队列管理器在用户模式下运行,因此有一个可寻址的 2GB 虚拟地址空间可供使用。每条消息的数据都存储在 RAM 中,由系统的分页文件或内存映射文件备份。 MSMQ 使用内存映射文件来存储快速和可恢复的消息。由于我们被限制为 2GB 的可寻址内存,我们被限制为磁盘上 2GB 的消息。考虑到 MSMQ 代码及其内部数据结构所使用的内存,以及在磁盘上存储消息文件的文件分配,我们最终可以在磁盘上存储 1.4GB 到 1.6GB 的消息。

注意   通过在 MSMQ 服务上启用 3GB 调整,可以将此 1.6GB 的限制提高到大约 2.6GB。有关如何启用 3GB 调整的更多信息,请参阅 Q171793

编辑:调整链接似乎已损坏。我相信它应该指向here

关于更高版本的 MSMQ,John 在a blog post 中讨论了这个问题。

最大消息数

这个不是那么容易解决的。从我的资源不足的帖子中,我们知道每条消息需要 75 字节的内核内存来索引,因此,例如,200 万条消息需要大约 150 兆字节。因此,您需要做的似乎就是添加更多 RAM。但是,在查看了 32 位和 64 位内存架构的比较之后,您将很快不得不迁移到 64 位平台以充分利用您的投资,因为 32 位机器最多可以使用 450 MB 的分页池内存无论安装多少 RAM。

但是,同样,如果您想计算出多少 RAM 将生成容纳十亿 MSMQ 消息所需的分页池内存,那么您的设计规范需要进行一些认真的审查。

【讨论】:

  • 调优的链接好像坏了。不幸的是,它直接从文章中引用:/ 我确实找到了另一篇有用的文章,其中包含更多关于此事的详细信息:blogs.msdn.com/b/johnbreakwell/archive/2006/09/18/…
  • 比那篇博客文章更好的是““MSMQ 的限制是什么?”如果我每次都有一分钱……”blogs.msdn.com/b/johnbreakwell/archive/2008/02/29/…
  • 应该忽略上面最初引用的 MSDN 段落,因为它仅适用于 Windows 2000 (MSMQ 2.0) 及之前的版本。如果可以的话,我会把这篇文章烧掉,因为它现在只是误导而不是通知。
猜你喜欢
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 2017-09-16
  • 2013-09-09
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多