原文链接:https://docs.oracle.com/cd/E19148-01/820-0843/6nci9sed1/index.html
消息堆积
症状:
消息的生成发生了延迟,或者生成的消息被代理拒绝。
消息到达使用方的时间过长。
代理(或特定目的地)中的消息数或消息字节数随着时间的推移稳定增加。
要查看消息是否在堆积,请检查代理中的消息数或消息字节数如何随时间的推移而改变,并与配置的限制进行比较。首先检查配置的限制:
imqcmd query bkr
注 –
imqcmd metrics bkr 子命令不会显示此信息。
然后检查每个目的地中的消息堆积情况。
imqcmd list dst
要检查消息是否已超出配置的目的地或代理范围的限制,请在代理日志中检查如下条目:
[B2011]:存储来自 … 的 JMS 消息失败。
此条目后面接有另一个标识已超出限制的条目。
可能的原因:
主题目的地上有非活动的长期订阅:
如果长期订阅是非活动的,则消息会存储在目的地中,直到相应的使用方变为活动状态且能够使用这些消息为止。
确认问题的起因:检查每个主题目的地上的长期订阅的状态:
imqcmd list dur -d destName
解决此问题:
-
清除所有存在问题的长期订阅的消息(请参见管理长期订阅)。
-
指定主题的消息限制以及限制行为属性(请参见表 15–1)。例如,您可以指定 REMOVE_OLDEST 和 REMOVE_LOW_PRIORITY 限制行为,这些行为删除堆积在内存中的消息。
-
清除来自相应目的地的所有消息(请参见清除物理目的地)。
-
通过重写生成方客户端以便对每个消息都设置一个生存时间值,来限制消息可以在内存中保留的时间。您可以通过设置 imqOverrideJMSExpiration 和 imqJMSExpiration 连接工厂属性来覆盖共享一个连接的所有生成方的任何此类设置(请参见消息头覆盖)。
队列中可以使用消息的使用方太少:
如果消息可以传送到的活动使用方太少,队列目的地可能会随着消息的堆积而堆满了后备队列。只要有下列任何原因,都会发生此情况:目的地的活动使用方太少;使用方客户端建立连接失败;活动使用方没有使用与队列中的消息匹配的选择器。
确认问题的起因:要确定使用方不可用的原因,请检查目的地上活动使用方的数目:
imqcmd metrics dst - n destName -t q -m con
解决此问题:根据使用方不可用的原因,
-
通过启动其他使用方客户端来为队列创建更多的活动使用方。
-
调整 imq.consumerFlowLimit 代理属性以优化向多个使用方的队列传送(请参见多使用方队列性能)。
-
指定队列的消息限制以及限制行为属性(请参见表 15–1)。例如,您可以指定 REMOVE_OLDEST 和 REMOVE_LOW_PRIOROTY 限制行为,这些行为删除堆积在内存中的消息。
-
清除来自相应目的地的所有消息(请参见清除物理目的地)。
-
通过重写生成方客户端以便对每个消息都设置一个生存时间值,限制消息可以在内存中保留的时间。您可以通过设置 imqOverrideJMSExpiration 和 imqJMSExpiration 连接工厂属性来覆盖共享一个连接的所有生成方的任何此类设置(请参见消息头覆盖)。
消息使用方的处理速度太慢,跟不上消息生成方的速度:
在这种情况下,主题的订阅者或队列的接收者使用消息的速度要比生成方发送消息的速度慢。有一个或多个目的地因为这种不平衡而堆满了消息。
确认问题的起因:检查消息流入和流出代理的速率:
imqcmd metrics bkr -m rts
然后检查每个单独目的地的流速:
imqcmd metrics bkr -t destType -n destName - m rts
解决此问题:
-
优化使用方客户端代码。
-
对于队列目的地,增大活动使用方的数目(请参见多使用方队列性能)。
客户端确认处理减慢了消息的使用:
有两个因素影响客户端确认处理:
在处理客户端确认的过程中会消耗大量的代理资源。因此,如果使用方客户端会一直阻塞到代理对客户端确认进行确认时为止,则对于这样的确认模式,消息的使用会变慢。
JMS 有效负荷消息和 Message Queue 控制消息(例如客户端确认)共享同一连接。因此,控制消息可能会被 JMS 有效负荷消息阻挡,从而使消息的使用变慢。
确认问题的起因:
-
检查与包流相关的消息流。如果每秒包数与消息数不成比例,则客户端确认可能有问题。
-
检查客户端是否收到以下异常:
JMSException [C4000]:包确认失败
解决此问题:
-
修改客户端使用的确认模式:例如,切换到 DUPS_OK_ACKNOWLEDGE 或 CLIENT_ACKNOWLEDGE。
-
如果使用 CLIENT_ACKNOWLEDGE 或事务会话,则将更多数目的消息组合到一个确认中。
-
调整使用方和连接流控制参数(请参见客户端运行时环境消息流调整)。
代理无法适应生成消息的速度:
在这种情况下,消息流入代理的速度比代理可以将它们路由并发送到使用方的速度要快。代理的迟缓可能由下列任一或全部限制所导致:
-
CPU
-
网络套接字读/写操作
-
磁盘读/写操作
-
内存分页
-
持久性存储库
-
JVM 内存限制
确认问题的起因:检查有无其他可能的原因导致此问题。
解决此问题:
-
升级计算机或数据存储库的速度。
-
使用代理群集在多个代理实例之间分布负载。
客户端代码缺陷:使用方不确认消息:
消息会保留在目的地中,直到消息所发送到的所有使用方都进行了确认为止。如果客户端没有确认已使用消息,则该消息会在目的地中堆积,而不会被删除。
例如,客户端代码可能存在以下缺陷:
-
使用 CLIENT_ACKNOWLEDGE 确认模式或事务会话的使用方可能没有定期调用 Session.acknowledge 或 Session.commit。
-
使用 AUTO_ACKNOWLEDGE 确认模式的使用方可能因为某种原因而挂起。
确认问题的起因:首先检查本节中列出的其他所有可能的原因。其次,使用以下命令列出目的地:
imqcmd list dst
请注意 UnAcked 标题下列出的消息数目是否与目的地中的消息数目相同。此标题下的消息已发送到使用方但未得到确认。如果此数目与消息总数相同,则说明代理已发送所有消息,正在等待确认。
解决此问题:请求应用程序开发者帮助调试此问题。