内存队列2.0中用于存储消息的RAM超过分配的内存时发生错误。

本文提供解决方案来处理在 Microsoft Message Queuing 2.0 (MSMQ 2.0) 中用于存储消息的 RAM 超过分配内存时出现的问题。

原产品版本:Microsoft 消息队列
原始 KB 数: 899613

症状

当您向队列发送消息时,MSMQ 不会接受您发送的消息。 相反,MSMQ 会生成一个“资源不足”错误消息。 您在使用 MSMQ 2.0 发送消息的应用程序中收到此错误消息。

当出现此问题时,以下信息可能会出现在 .NET Framework 服务或应用程序的堆栈跟踪中:

异常类型:System.Messaging.MessageQueueException
消息队列错误代码: 资源不足
信息:资源不足,无法执行操作。
ErrorCode:-2147467259
TargetSite:Void SendInternal(System.Object、System.Messaging.MessageQueueTransaction、System.Messaging.MessageQueueTransactionType)
帮助链接: 空
来源:System.Messaging

此外,上述信息会记录在应用程序日志中。 在 COM+ 排队组件 (QC) 应用程序中,上述信息可能会记录在应用程序日志中。 此问题在以下条件成立时发生:

  • 您尝试在 MSMQ 中发送消息。

  • 当前用于运行服务和存储消息的已分配内存已达到2千兆字节(GB)。 默认情况下,Windows 2000 为每个进程分配 2 GB 的可寻址内存。

    MSMQ 服务加载后,MSMQ 2.0 可以用来存储消息的默认分配内存为 1.6 GB 到 1.8 GB 之间。

    注意事项

    如果您使用3GB开关,分配的内存将在2 GB到2.5 GB之间。

    消息存储文件是内存映射文件。 因此,您可以通过检查 MSMQ 存储文件夹的大小来查看是否超出了限制。 该文件夹通常位于%WinDir%\System32\MSMQ存储文件夹中。 但是,可以将存储文件夹配置到其他位置。 要查看存储文件夹是否已配置到另一个位置,请检查控制面板中的 MSMQ 工具的存储选项卡中的消息文件夹字段。

原因

此问题发生可能是由于以下一个或多个原因:

  • 处理排队消息的应用程序正在出现困难。 然而,消息继续以比应用程序可以读取和处理消息的速度更快的速度到达队列中。

  • 队列中已启用日志记录。 然而,导致消息累积的数据尚未被删除。

  • 队列中启用了死信处理。 此外,可用于存储死信消息的已分配内存量已达到或超过。

  • 消息已在外发队列中积累,因为目标队列不可用。

决议

解决此问题的方法取决于 MSMQ 服务的当前状态。 在解决此问题之前,您必须停止写入队列的服务或应用程序。

如果 MSMQ 正在运行

确定哪些队列已积累消息。 要做到这一点,请使用以下方法之一:

  • 手动检查队列,使用 MSMQ 接口。 MSMQ接口位于计算机管理控制台中。

  • 在性能监视器中,设置 MSMQ 队列性能对象上的所有计数器。 然后,选择报告视图。 在报告视图中,您可以看到每个队列中的消息数量。

完成确定哪些队列积累了消息后,您需要确定消息积累的原因。 可能有几个原因导致消息在队列中累积。 这些原因包括以下几点:

  • 正在发送消息队列中的消息无法到达其目的地。 如果消息无法到达目的地,请确保目的地计算机可以接收消息。 如果这些消息已过时或没有值,请清除队列。

  • 应该接收消息的应用程序已停止或进入错误状态。 如果这些条件中的任何一个为真,请在该应用程序中解决问题。

  • 死信队列或日记队列中的消息已保留。 这些消息尚未删除或处理。 如果这些消息已被保留,请确定保留这些消息的目的。 用于记录消息的选项经常用于测试。

测试完成后,此选项可能会无意中保持启用状态。 如果消息已死信,则未在指定时间内处理或传递消息。 如果开启了死信处理或日志功能,则应有一个进程从队列中读取这些消息。 当您确定了消息积压的队列时,可以删除这些积压的消息。

如果 MSMQ 没有运行,并且您无法手动启动它

注意事项

  • 在对 MSMQ 存储文件夹中的文件进行任何更改之前,建议使用 MQbkup.exe备份当前的 MSMQ 环境。 这一步非常重要,如果您需要产品支持服务的帮助。

  • 由于 MSMQ 已进入不稳定状态,您可能无法恢复所有消息。 如果您在使用以下步骤恢复消息时遇到困难,并且这些数据非常重要,请联系产品支持服务以获得帮助。

若要使用 MQbkup.exe备份 MSMQ 配置,请执行以下步骤。

注意事项

在运行 MQbkup.exe 之前,选择一个文件夹来备份 MSMQ 文件。 该文件夹必须位于至少有 2.5 GB 可用空间的磁盘上。

  1. 打开命令提示符窗口。

  2. 将目录更改为%WinDir%\System32

  3. 运行命令:

    MQbkup.exe -b Drive :\ Folder to Put Backup Files
    
  4. 注意备份 MSMQ 文件的文件夹位置。

通过使用 3-GB 开关启动服务器

注意事项

3GB 交换机只是 Windows 2000 高级服务器的一个选项。 对于 Windows 2000 Server 和 Windows 2000 Professional,请转到“ 手动恢复邮件 ”部分。

默认情况下,Windows 2000 为每个进程分配 2 GB 的可寻址内存。 这个问题是由于MSMQ使用了全部分配导致的。 这种行为阻止了服务的正常重启。 如果使用3GB开关,Windows 2000高级服务器将为每个进程分配3GB的可寻址内存。 此配置为 MSMQ 提供足够的可寻址内存,以便在重启服务器后加载服务和消息存储文件。 此交换机将 MSMQ 存储增加到 2 GB 到 2.5 GB。

警告

此配置可能会影响服务器上的其他资源。 我们建议您在完成故障排除后移除 3GB 开关。 此配置不旨在永久解决该问题。 然而,您可以使用此配置来访问 MSMQ,以便您可以执行如果 MSMQ 正在运行部分中的步骤。

要了解如何配置 Windows 以使用 3-GB 开关运行,请参阅 Windows 2000 帮助文件中的在您的应用程序中启用应用程序内存调优支持主题。

要手动恢复您的消息

注意事项

  • 仅当 MSMQ 未运行时,才按照这些步骤操作。
  • 由于MSMQ处于不稳定状态而无法启动,您可能无法恢复所有消息。

警告

该过程可能导致应用程序接收事务消息的顺序与消息最初到达的顺序不同。

  1. 创建一个临时文件夹来存放你的消息存储文件。 不要将此文件夹放在 MSMQ 文件夹中。

  2. 只选择文件扩展名为.mq的文件。

    警告

    MSMQ 存储文件夹中的某些文件对于 MSMQ 正确运行至关重要。 请确保仅选择扩展名为 .mq 的文件。

  3. 将所选文件移动到您在步骤1中创建的文件夹中。

  4. 确保 MSMQ 数据访问驱动程序未启动。 要执行此操作,请在命令提示符下运行以下命令:

    Net Stop MQAC /y
    
  5. 启动 MSMQ 服务。 若要执行此操作,请在命令提示符下运行以下命令:

    Net Start MSMQ
    

    注意事项

    如果消息中的数据不重要,而您只想让 MSMQ 恢复上线,那么您可以停下来。

  6. 验证服务现在可以启动后,停止该服务。 若要执行此操作,请在命令提示符下运行以下命令:

    Net Stop MQAC /y
    

    此命令将停止 MSMQ 服务和数据访问驱动程序。

  7. 在步骤5中移动消息存储文件的文件夹中,请注意,一些文件名是 p数字.mq 格式,而另一些文件名是 l数字.mq 格式。 这些文件是成对存储的。 每个p文件都有一个对应的l文件。

    注意文件修改的日期。 选择最旧的 p 文件和相应的 l 文件。 将这些文件移动到原始 MSMQ 存储文件夹。

  8. 在第5步中运行命令以启动MSMQ服务。 如果服务启动,请按照如果 MSMQ 正在运行部分中的步骤,确定消息正在积累在哪些队列中以及如何处理这些消息。

  9. 在您从队列中移除堆积的消息之后,重复步骤6到步骤8,直到所有消息文件都返回到MSMQ存储文件夹,并且已将所有堆积的消息从队列中移除为止。

    注意事项

    请勿一次性将超过1.6 GB的数据移回到MSMQ存储文件夹。 如果您这样做,服务可能无法启动。

重现问题的步骤

在运行 Windows 2000 Server 的计算机上,向本地队列发送消息,直到您用于发送消息的应用程序收到0x00e0027异常错误。

MSMQ 2.0 将消息存储在内存映射文件中。 在运行 Windows 2000 Server 的计算机上,MSMQ 2.0 的默认可用内存分配量为 2 GB。 MSMQ 2.0 的组件加载到计算机上后,可供 MSMQ 2.0 使用的分配内存减少到大约 1.6 GB 到 1.8 GB 之间。

如果您在Boot.ini文件中启用了3-GB开关,分配给MSMQ 2.0的可用内存量将增加到3 GB。 MSMQ 2.0 的组件加载到计算机后,可供 MSMQ 2.0 使用的分配内存减少到 2.7 GB。

然而,额外分配的内存也从内核中占用了大约1 GB的已分配内存。 这种行为可能会影响系统性能,并影响执行文件输入输出操作的应用程序。

我们不建议您仅仅使用 3-GB 开关来增加 MSMQ 2.0 可用的分配内存量。 相反,我们建议您设置计算机配额,以防止< c0 >症状< /c0 >部分中提到的问题。

有关更多信息,请参阅 如何在 Microsoft 消息队列中设置计算机配额和队列配额