Sun Java System Message Queue 3.7 UR1 管理指南

第 12 章 问题疑难解答

本章介绍了如何理解和解决以下问题:

出现问题时,检查所安装 Message QueueTM 软件的版本号会很有帮助。可以使用版本号来确保目前正在使用的文档版本与软件版本相匹配。向 Sun 报告问题时,也需要用到版本号。要检查版本号,请执行以下命令:

imqcmd -v

客户端无法建立连接

症状:

可能的原因:

可能的原因:客户端应用程序不关闭连接,导致连接数超出资源限制。

确认问题的起因:列出代理的所有连接:

imqcmd list cxn

输出结果将列出所有连接以及发起每个连接的主机,从而显示具体是哪些客户端的打开连接数超出限制。

解决此问题:重写有问题的客户端,以关闭未使用的连接。

可能的原因:代理未运行或者网络连接有问题。

确认问题的起因:

解决此问题:

可能的原因:连接服务处于非活动状态或者已暂停。

确认问题的起因:检查所有连接服务的状态:

imqcmd list svc

如果某个连接服务的状态显示为 unknownpaused,客户端将无法使用该服务建立连接。

解决此问题:

可能的原因:相对于所需的连接数而言,可用线程数不足。

确认问题的起因:在代理日志中检查下面的条目:

警告 [B3004]:服务上没有可以用来处理新连接的线程...关闭新连接。

此外,请检查连接服务上的连接数以及当前使用的线程数(使用以下格式之一):

imqcmd query svc -n serviceName imqcmd metrics svc -n serviceName -m cxn

每个连接都需要两个线程:一个用于传入消息,另一个用于传出消息(请参见线程池管理)。

解决此问题:

可能的原因:相对于 Solaris 或 Linux 平台上需要的连接数而言,文件描述符不足。

有关此问题的详细信息,请参见设置文件描述符限制

确认问题的起因:在代理日志中查找与下面显示的条目类似的条目:

打开了太多文件

解决此问题:增大文件描述符限制,如 ulimit 手册页中所述。

可能的原因:TCP 后备队列限制了可以同时建立的新连接请求的数目。

TCP 后备队列限制可以同时存储在系统后备队列 (imq.portmapper.backlog) 中的连接请求数,超过此限制后,端口映射器将拒绝额外的请求。(在 Windows 平台上,有一种硬编码的后备队列限制:Windows 台式机限制为 5,而 Windows 服务器限制为 200。)

出于后备队列限制而拒绝请求通常是一种由于同时连接请求数过多而导致的瞬态现象。

确认问题的起因:检查代理日志。首先,检查代理是否在接受某些连接的同时拒绝其他连接。其次,检查说明拒绝连接原因的消息。如果找到此类消息,则说明问题可能不是由 TCP 后备队列引起的,因为代理不记录由于 TCP 后备队列而引起的连接拒绝事件。如果记录了一些成功连接,但未记录任何连接拒绝事件,则问题可能是由 TCP 后备队列引起的。

解决此问题:

可能的原因:操作系统限制了并发连接数。

Windows 操作系统许可证对支持的并发远程连接数进行了限制。

确认问题的起因:检查是否有可用于连接的足够线程(使用 imqcmd query svc),并检查您的 Windows 许可协议的条款。如果您可以从本地客户端建立连接,但不能从远程客户端建立连接,则操作系统的限制可能就是问题的起因。

解决此问题:

可能的原因:对用户的验证或授权失败。

验证可能因为以下原因失败:

确认问题的起因:检查代理日志中的条目,查看是否有 Forbidden 错误消息。此消息指明存在验证错误,但不会指明该错误的原因。

解决此问题:

连接的吞吐量太低

症状:

可能的原因:

可能的原因:网络连接或 WAN 太慢。

确认问题的起因:

解决此问题:升级网络链路。

可能的原因:与 TCP 相比,连接服务协议本身就慢。

例如,基于 SSL 的协议或基于 HTTP 的协议要比 TCP 慢(请参见传输协议)。

确认问题的起因:如果您使用的是基于 SSL 或基于 HTTP 的协议,请尝试使用 TCP,然后比较传送时间。

解决此问题:应用程序要求通常会指定要使用的协议,因此除了按调整传输协议中所述尝试调整协议之外,您几乎无法执行任何其他操作。

可能的原因:连接服务协议未进行优化调整。

确认问题的起因:尝试调整协议,确定是否发生了变化。

解决此问题:尝试按调整传输协议中所述调整协议。

可能的原因:消息太大,以致于占用了过多的带宽。

确认问题的起因:尝试使用较小的消息运行基准测试程序。

解决此问题:

可能的原因:使连接吞吐量变低的可能原因也就是消息传送过程中某个步骤的瓶颈。

确认问题的起因:如果上述任何一条似乎都不是造成连接吞吐量变低的原因,请参见影响性能的因素以了解其他可能的瓶颈,并检查与以下问题相关的症状:

解决此问题:请遵循上述有关疑难解答的各节中所提供的问题解决原则。

客户端无法创建消息生成方

症状:

可能的原因:

可能的原因:物理目的地被配置为仅允许有限数目的生成方。

限制某个物理目的地所支持的生成方 (maxNumProducers ) 数目是避免消息在该物理目的地上堆积的方法之一。

确认问题的起因:检查物理目的地:

imqcmd query dst

(请参见显示有关物理目的地的信息)。输出结果将显示当前的生成方数目以及 maxNumProducers 的值。如果这两个值相同,则说明生成方的数目已达到所配置的限制。如果新的生成方被代理拒绝,代理将返回异常

ResourceAllocationException [C4088]:已达到 JMS 目的地限制

且在代理日志中生成如下条目:

[B4183]:无法将生产方添加到目的地

解决此问题:增加 maxNumProducers 属性的值(请参见更新物理目的地属性)。

可能的原因:由于访问控制属性文件中的设置,用户未获得创建消息生成方的授权。

确认问题的起因:如果新的生成方被代理拒绝,代理将返回异常

JMSSecurityException [C4076]:客户端没有在目的地上创建生成方的权限

且在代理日志中记录以下条目:

[B2041]:目的地上的生成方被拒绝 [B4051]:禁用 guest

解决此问题:更改访问控制属性,允许用户生成消息(请参见对物理目的地的访问控制)。

消息的生成过程延迟或速度减慢

症状:

可能的原因:

可能的原因:代理上堆满了后备队列,使得消息生成方的执行速度变慢。

堆满后备队列的代理将消息堆积在代理内存中。当物理目的地内存中的消息数或消息字节数达到配置的限制时,代理会尝试根据指定的限制行为来节省内存资源。以下限制行为会使消息生成方速度减慢:

同样,如果代理范围的内存(对于所有物理目的地)中消息数或消息字节数达到配置的限制,代理将尝试通过拒绝最新的消息来节省内存资源。另外,如果达到了系统内存限制(由于物理目的地或代理范围限制设置不正确),代理将采取愈加严格的操作来防止内存过载。这些操作包括限制消息生成方。

确认问题的起因:如果某个消息因为达到了配置的消息限制而被代理拒绝,代理将返回异常

JMSException [C4036]:发生服务器错误

且在代理日志中生成以下条目:

[B2011]:存储来自 IMQconn 的 JMS 消息失败

随后又产生一条消息表明已达到内存限制:

[B4120]:无法在目的地 destName 上存储消息,因为会超出 maxNumMsgs 的容量。

如果超出的消息限制是在物理目的地上,或

[B4024]:已经超出目前系统中的最大消息数,正在拒绝消息。

如果消息限制是代理范围的。

通常,您可以在发生拒绝之前按如下方式检查消息限制情况:

解决此问题:

可能的原因:代理无法将持久性消息保存到数据存储库中。

如果代理无法访问数据存储库或者无法将持久性消息写入数据存储库,则生成方客户端将受阻。如前所述,如果达到了目的地或代理范围的消息限制,也会发生这种情况。

确认问题的起因:如果代理无法写入数据存储库,它将在代理日志中生成以下条目之一:

[B2011]:存储来自 connectionID 的 JMS 消息失败[B4004]:无法持续消息 messageID

解决此问题:

可能的原因:代理的确认超时时间太短。

由于连接太慢或代理反应迟缓(由于 CPU 占用率太高或者内存资源不足导致),代理用于确认收到持久性消息的时间比连接工厂的 imqAckTimeout 属性值所允许的时间要长。

确认问题的起因:如果超出了 imqAckTimeout 值,代理将返回异常

JMSException [C4000]:包确认失败

解决此问题:更改 imqAckTimeout 连接工厂属性的值(请参见可靠性和流控制)。

可能的原因:生成方客户端遇到了 JVM 限制。

确认问题的起因:

解决此问题:调整 JVM(请参见Java 虚拟机调整)。

消息堆积

症状:

要查看消息是否在堆积,请检查代理中的消息数或消息字节数如何随时间的推移而改变,并与配置的限制进行比较。首先检查配置的限制:

imqcmd query bkr


注 –

imqcmd metrics bkr 子命令不会显示此信息。


然后检查每个目的地中的消息堆积情况。

imqcmd list dst

要检查消息是否已超出配置的目的地或代理范围的限制,请在代理日志中检查如下条目:

[B2011]:存储来自 的 JMS 消息失败。

此条目后面接有另一个标识已超出限制的条目。

可能的原因:

可能的原因:主题目的地上有非活动的长期订阅。

如果长期订阅是非活动的,则消息会存储在目的地中,直到相应的使用方变为活动状态且能够使用这些消息为止。

确认问题的起因:检查每个主题目的地上的长期订阅的状态:

imqcmd list dur -d destName

解决此问题:

可能的原因:队列中可以使用消息的使用方太少。

如果消息可以传送到的活动使用方太少,队列目的地可能会随着消息的堆积而堆满了后备队列。只要有下列任何原因,都会发生此情况:

确认问题的起因:要确定使用方不可用的原因,请检查目的地上活动使用方的数目:

imqcmd metrics dst - n destName -t q -m con

解决此问题:根据使用方不可用的原因,

可能的原因:消息使用方的处理速度太慢,跟不上消息生成方的速度。

在这种情况下,主题的订阅者或队列的接收者使用消息的速度要比生成方发送消息的速度慢。有一个或多个目的地因为这种不平衡而堆满了消息。

确认问题的起因:检查消息流入和流出代理的速率:

imqcmd metrics bkr -m rts

然后检查每个单独目的地的流速:

imqcmd metrics bkr -t destType -n destName - m rts

解决此问题:

可能的原因:客户端确认处理减慢了消息的使用。

有两个因素影响客户端确认处理:

确认问题的起因:

解决此问题:

可能的原因:代理无法适应生成消息的速度。

在这种情况下,消息流入代理的速度比代理可以将它们路由并发送到使用方的速度要快。代理的迟缓可能由下列任一或全部限制所导致:

确认问题的起因:检查有无其他可能的原因导致此问题。

解决此问题:

可能的原因:客户端代码缺陷:使用方不确认消息。

消息会保留在目的地中,直到消息所发送到的所有使用方都进行了确认为止。如果客户端没有确认已使用消息,则该消息会在目的地中堆积,而不会被删除。

例如,客户端代码可能存在以下缺陷:

确认问题的起因:首先检查本节中列出的其他所有可能的原因。其次,使用以下命令列出目的地:

imqcmd list dst

请注意 UnAcked 标题下列出的消息数目是否与目的地中的消息数目相同。此标题下的消息已发送到使用方但未得到确认。如果此数目与消息总数相同,则说明代理已发送所有消息,正在等待确认。

解决此问题:请求应用程序开发者帮助调试此问题。

代理吞吐量呈间歇性

症状:

可能的原因:

可能的原因:代理的内存资源非常低。

由于目的地和代理限制设置不当,代理采取了越来越严格的措施以防止内存过载,这样就导致代理变得非常迟缓,直到堆积的消息得到清除为止。

确认问题的起因:在代理日志中检查内存低的情况:

[B1089]:内存不足,代理正在尝试释放资源

该情况后面会接有一个描述新内存状态和已用内存总量的条目。另外请检查 JVM 堆中的可用内存:

imqcmd metrics bkr -m cxn

当总 JVM 内存接近 JVM 内存最大值时,可用内存就会很低。

解决此问题:

可能的原因:正在发生 JVM 内存回收(垃圾收集)。

内存回收会定期清扫整个系统,以释放内存。发生此操作时,所有的线程都会阻塞。要释放的内存量以及 JVM 堆的大小越大,因内存回收而导致的延迟就越长。

确认问题的起因:监视计算机上的 CPU 使用率。发生内存回收时,CPU 使用率会下降。

另外,使用以下命令行选项启动代理:

- vmargs -verbose:gc

其标准输出指明发生内存回收的时间。

解决此问题:在多个 CPU 的计算机中,将内存回收设置为并行发生:

-XX:+UseParallelGC=true

可能的原因:JVM 使用实时编译器来提高性能。

确认问题的起因:检查有无其他可能的原因导致此问题。

解决此问题:让系统运行一段时间,性能应该会有所改善。

消息无法到达使用方

症状:

可能的原因:

可能的原因:限制行为导致消息在代理上被删除。

如果目的地内存中的消息数或消息字节数达到了配置限制,代理将尝试节省内存资源。当达到限制时,代理将采用下列三个可配置的行为,从而导致消息丢失:

确认问题的起因:检查停用消息队列,如停用消息队列包含消息中所述。具体地说,是使用“消息的数目或者其大小超出目的地限制”中的说明。查找 REMOVE_OLDEST REMOVE_LOW_PRIORITY 原因。

解决此问题:增加目的地限制。例如:

imqcmd update dst -n MyDest - o maxNumMsgs=1000

可能的原因:消息超时值即将到期。

代理将删除超时值已过期的消息。如果目的地上完全堆满了消息,生存时间值过短的消息将被删除。

确认问题的起因:使用 QBrowser 演示应用程序来查看停用消息队列内容并查看消息是否超时。要了解 QBrowser 演示程序特定于平台的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置并查看“示例应用程序和位置”表。

下面是 Windows 平台中的一个调用示例:

cd \MessageQueue3\demo\applications\qbrowser java QBrowser

QBrowser 主窗口出现后,选择队列名称 mq.sys.dmq,然后单击 "Browse"。将出现如下所示的列表:

QBrowser 显示 mq.sys.dmq 的消息。每条消息都包括编号、时间戳、类型、模式以及优先级。

双击消息可显示该消息的详细信息:

消息详细信息窗口。顶部窗格显示消息;中间窗格显示其属性;底部窗格包含消息。

请注意消息的 JMS_SUN_DMQ_UNDELIVERED_REASON 属性值是否为 EXPIRED

解决此问题:联系应用程序开发者,请他们提高生存时间值。

可能的原因:时钟不同步。

如果时钟之间不同步,则代理对消息生命周期的计算可能有错误,从而导致消息超过它们的到期时间而被删除。

确认问题的起因:在代理日志文件中,查找下列任一消息:B2102B2103B2104。这些消息均报告检测到可能的时钟脉冲相位差。

解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。

可能的原因:使用方客户端未能在某个连接上启动消息传送。

除非客户端代码建立了连接,并在该连接上启动了消息传送,否则消息将无法传送。

确认问题的起因:检查客户端代码是否能建立连接并启动消息传送。

解决此问题:重写客户端代码,以建立连接并启动消息传送。

停用消息队列包含消息

症状:


Listing all the destinations on the broker specified by:
---------------------------------
Host         Primary Port
---------------------------------
localhost    7676
----------------------------------------------------------------------
   Name     Type    State   Producers  Consumers  Msgs
                                         Total    Count  UnAck  Avg Size
------------------------------------------------- ----------------------
MyDest      Queue  RUNNING       0          0        5      0    1177.0
mq.sys.dmq  Queue  RUNNING       0          0       35      0    1422.0
Successfully listed destinations.

在本示例中,停用消息队列 mq.sys.dmq 包含 35 条消息。

可能的原因:

可能的原因:消息的数目或者其大小超出目的地限制。

确认问题的起因:使用 QBrowser 演示应用程序来查看停用消息队列的内容。要了解 QBrowser 演示程序特定于平台的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置并查看“示例应用程序和位置”表。

下面是 Windows 平台中的一个调用示例:

cd \MessageQueue3\demo\applications\qbrowser java QBrowser

QBrowser 主窗口出现后,选择队列名称 mq.sys.dmq,然后单击 "Browse"。将会出现如前面“消息超时值即将到期”中所示的列表。双击消息可显示该消息的详细信息,如“消息超时值即将到期”中所示。

请注意下列消息属性的值:

请注意 JMS 标题下面的 JMSDestination 值,以确定消息将停用的目的地。

解决此问题:增加目的地限制。例如:

imqcmd update dst - n MyDest -o maxNumMsgs=1000

可能的原因:代理时钟和生成方时钟不同步。

确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。

在代理日志文件中,查找下列任一消息:B2102 B2103B2104。这些消息均报告检测到可能的时钟脉冲相位差。

解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。

可能的原因:消息超时前,使用方未接收到消息。

确认这是否就是问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。

检查目的地中是否有任何使用方。例如:

imqcmd query dst -t q -n MyDest

检查列出的“当前活动使用方”值。如果有活动使用方,则下面的某一项为真:

解决此问题:请求应用程序开发者提高消息的生存时间值。

可能的原因:相对使用方数目而言,生成方太多。

确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值。如果原因是 REMOVE_OLDESTREMOVE_LOW_PRIORITY,请使用 imqcmd query dst 命令来检查目的地中的生成方和使用方的数目。如果生成方的数目超过使用方的数目,则生成率可能会远远超出使用率。

解决此问题:添加更多的使用方客户端,或者使用如下所示的命令,将目的地限制行为设置为 FLOW_CONTROL(该限制行为通过使用率来控制生成率):

imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL

可能的原因:生成方比使用方的速度快。

确认问题的起因:要确定较慢的使用方是否会导致生成方的速度降低,请使用如下所示的命令,将目的地限制行为设置为 FLOW_CONTROL(该限制行为通过使用率来控制生成率):

imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL

使用如下所示的命令,使用度量来检查目的地的输入和输出:

imqcmd metrics dst - n myDst -t q -m rts

在度量输出中,检查以下值:

由于流控制使生成与使用协调一致,因此请注意生成是否减慢或停止。如果生成减慢或停止,则说明生成方和使用方的处理速度不一致。也可以使用 imqcmd list dst 命令,检查未确认的 (UnAcked) 发送消息的数目。如果未确认的消息数目小于目的地大小,则表明目的地尚有额外的容量,它受到客户端流控制的抑制。

解决此问题:如果生成率始终高于使用率,可以考虑有规律地使用流控制以使系统保持协调一致。此外,使用后面各节的内容,考虑并尝试消除下列可能的因素:

可能的原因:使用方太慢。

确认问题的起因:使用度量来确定生成和使用的速率,如前面“生成方比使用方的速度快”中所述。

解决此问题:

可能的原因:客户端不提交消息。

确认问题的起因:与应用程序开发者进行确认以查明应用程序是否使用事务。如果应用程序使用事务,则按如下所示列出活动事务:

imqcmd list txn

下面是一个命令输出示例:


----------------------------------------------------------------------
Transaction ID       State    User name  # Msgs/# Acks   Creation time
----------------------------------------------------------------------
6800151593984248832  STARTED  guest           3/2     7/19/04 11:03:08 AM

请注意消息和确认的数目。如果消息的数目很高,则生成方可能正在发送个别的消息,而未能提交事务。代理在收到提交之前,无法路由并传送该事务的消息。如果确认的数目很高,则使用方可能正在发送个别消息的确认,而未能提交事务。代理在收到提交之前,无法删除该事务的确认。

解决此问题:联系应用程序开发者以修复编码错误。

可能的原因:使用方未能确认消息。

确认问题的起因:联系应用程序开发者以确定应用程序使用的是基于系统的确认还是基于客户端的确认。如果应用程序使用基于系统的确认,则跳过本节;如果应用程序使用基于客户端的确认 (CLIENT_ACKNOWLEDGE),请先使用如下命令减少客户端中存储的消息数:

imqcmd update dst -n myDst -t q -o consumerFlowLimit=1

其次,确定是因为代理由于使用方速度慢而缓冲消息,还是因为使用方处理消息的速度很快但未对其进行确认。使用以下命令列出目的地:

imqcmd list dst

在提供用户名和密码后,将显示类似以下内容的输出:


Listing all the destinations on the broker specified by:
---------------------------------
Host         Primary Port
---------------------------------
localhost    7676
----------------------------------------------------------------------
   Name     Type    State   Producers  Consumers  Msgs
                                         Total    Count  UnAck  Avg Size
------------------------------------------------ -----------------------
MyDest      Queue  RUNNING       0          0        5    200    1177.0
mq.sys.dmq  Queue  RUNNING       0          0       35      0    1422.0
Successfully listed destinations.

未确认数值表示代理已发送且正在等待确认的消息数。如果此数值较高或不断增加,则说明代理正在发送消息,因此不等待速度较慢的使用方。还说明使用方未确认消息。

解决此问题:联系应用程序开发者以修复编码错误。

可能的原因:长期使用方处于非活动状态。

确认问题的起因:使用以下命令格式查看主题的长期订户:

imqcmd list dur -d topicName

解决此问题:

可能的原因:发生意外的代理错误。

确认问题的起因:使用 QBrowser 对消息进行检查,如前面“生成方比使用方的速度快”中所述。如果 JMS_SUN_DMQ_UNDELIVERED_REASON 的值是 ERROR,则说明代理发生错误。

解决此问题: