出现问题时,检查所安装 Message QueueTM 软件的版本号会很有帮助。可以使用版本号来确保目前正在使用的文档版本与软件版本相匹配。向 Sun 报告问题时,也需要用到版本号。要检查版本号,请执行以下命令:
imqcmd -v
症状:
客户端无法建立新连接。
客户端无法在连接失败时自动重新连接。
可能的原因:
可能的原因:客户端应用程序不关闭连接,导致连接数超出资源限制。
确认问题的起因:列出代理的所有连接:
imqcmd list cxn
输出结果将列出所有连接以及发起每个连接的主机,从而显示具体是哪些客户端的打开连接数超出限制。
解决此问题:重写有问题的客户端,以关闭未使用的连接。
可能的原因:代理未运行或者网络连接有问题。
确认问题的起因:
远程登录 (telnet) 到代理的主端口(例如,默认端口 7676),并验证代理是否以端口映射器输出作为响应。
验证代理进程是否正在主机上运行。
解决此问题:
启动代理。
修复网络连接问题。
可能的原因:连接服务处于非活动状态或者已暂停。
确认问题的起因:检查所有连接服务的状态:
imqcmd list svc
如果某个连接服务的状态显示为 unknown 或 paused,客户端将无法使用该服务建立连接。
解决此问题:
如果连接服务的状态显示为 unknown,它将不会出现在活动服务列表 (imq.service.active) 中。如果是基于 SSL 的服务,则还可能是因为服务未正确配置,导致代理在代理日志中生成下面的条目:
错误 [B3009]:无法启动服务 ssljms:[B4001]:无法打开 ssljms 服务的协议 tls...
后面说明了引起此异常的根源。
要正确配置 SSL 服务,请参见消息加密。
如果连接服务的状态显示为 paused,请恢复该服务(请参见暂停和恢复连接服务)。
可能的原因:相对于所需的连接数而言,可用线程数不足。
确认问题的起因:在代理日志中检查下面的条目:
警告 [B3004]:服务上没有可以用来处理新连接的线程...关闭新连接。
此外,请检查连接服务上的连接数以及当前使用的线程数(使用以下格式之一):
imqcmd query svc -n serviceName imqcmd metrics svc -n serviceName -m cxn
每个连接都需要两个线程:一个用于传入消息,另一个用于传出消息(请参见线程池管理)。
解决此问题:
如果使用专用线程池模型 (imq.serviceName.threadpool_model=dedicated),则最大连接数是该线程池中的最大线程数的一半。因此,要增加连接数,请增加线程池的大小 (imq.serviceName.max_threads) 或切换到共享线程池模型。
如果使用共享线程池模型 (imq. serviceName.threadpool_model=shared),则最大连接数是连接监视限制 (imq.serviceName.connectionMonitor_limit) 和最大线程数 (imq.serviceName.max_threads) 乘积的一半。因此,要增加连接数,可以增加线程池的大小或增大连接监视限制。
最终,可支持的连接数(或连接上的吞吐量)将达到输入/输出限制。这种情况下,可以使用多代理群集在群集内的代理实例之间分布连接。
可能的原因:相对于 Solaris 或 Linux 平台上需要的连接数而言,文件描述符不足。
有关此问题的详细信息,请参见设置文件描述符限制。
确认问题的起因:在代理日志中查找与下面显示的条目类似的条目:
打开了太多文件
解决此问题:增大文件描述符限制,如 ulimit 手册页中所述。
可能的原因:TCP 后备队列限制了可以同时建立的新连接请求的数目。
TCP 后备队列限制可以同时存储在系统后备队列 (imq.portmapper.backlog) 中的连接请求数,超过此限制后,端口映射器将拒绝额外的请求。(在 Windows 平台上,有一种硬编码的后备队列限制:Windows 台式机限制为 5,而 Windows 服务器限制为 200。)
出于后备队列限制而拒绝请求通常是一种由于同时连接请求数过多而导致的瞬态现象。
确认问题的起因:检查代理日志。首先,检查代理是否在接受某些连接的同时拒绝其他连接。其次,检查说明拒绝连接原因的消息。如果找到此类消息,则说明问题可能不是由 TCP 后备队列引起的,因为代理不记录由于 TCP 后备队列而引起的连接拒绝事件。如果记录了一些成功连接,但未记录任何连接拒绝事件,则问题可能是由 TCP 后备队列引起的。
解决此问题:
对客户端进行编程,使其在较短的时间间隔后重试所尝试的连接(此方法之所以生效通常是由于此问题的瞬态性)。
增加 imq.portmapper.backlog 的值。
检查客户端是否过于频繁地反复关闭和打开连接。
可能的原因:操作系统限制了并发连接数。
Windows 操作系统许可证对支持的并发远程连接数进行了限制。
确认问题的起因:检查是否有可用于连接的足够线程(使用 imqcmd query svc),并检查您的 Windows 许可协议的条款。如果您可以从本地客户端建立连接,但不能从远程客户端建立连接,则操作系统的限制可能就是问题的起因。
解决此问题:
升级 Windows 许可证,以允许更多的连接。
通过设置多代理群集在多个代理实例之间分布连接。
可能的原因:对用户的验证或授权失败。
验证可能因为以下原因失败:
密码错误
在用户系统信息库中没有该用户的条目
该用户没有对连接服务的访问权限
确认问题的起因:检查代理日志中的条目,查看是否有 Forbidden 错误消息。此消息指明存在验证错误,但不会指明该错误的原因。
如果使用的是基于文件的用户系统信息库,请输入下面的命令:
imqusermgr list -i instanceName -u userName
如果输出结果显示的是用户,说明可能提交了错误的密码。如果输出显示以下错误,则说明用户系统信息库中不存在该用户的条目:
错误 [B3048]:密码文件中不存在用户
如果使用的是 LDAP 服务器用户系统信息库,请使用相应的工具检查是否存在该用户的条目。
检查访问控制文件以查看是否对连接服务有访问限制。
解决此问题:
如果使用了错误的密码,请提供正确的密码。
如果在用户系统信息库中没有该用户的条目,请添加一个条目(请参见填充和管理用户系统信息库)。
如果该用户没有对连接服务的访问权限,则编辑访问控制属性文件以授予访问权限(请参见用于连接服务的访问控制)。
症状:
消息的吞吐量与预期不符。
支持的代理连接数受到限制不是如客户端无法建立连接中所述的原因,而是由于消息的输入/输出速率而导致的。
可能的原因:
可能的原因:网络连接或 WAN 太慢。
确认问题的起因:
Ping 网络,查看返回 ping 需要的时间,然后咨询网络管理员。
使用本地客户端发送并接收消息,并将传送时间与远程客户端(使用网络链路)的传送时间相比。
解决此问题:升级网络链路。
可能的原因:与 TCP 相比,连接服务协议本身就慢。
例如,基于 SSL 的协议或基于 HTTP 的协议要比 TCP 慢(请参见传输协议)。
确认问题的起因:如果您使用的是基于 SSL 或基于 HTTP 的协议,请尝试使用 TCP,然后比较传送时间。
解决此问题:应用程序要求通常会指定要使用的协议,因此除了按调整传输协议中所述尝试调整协议之外,您几乎无法执行任何其他操作。
可能的原因:连接服务协议未进行优化调整。
确认问题的起因:尝试调整协议,确定是否发生了变化。
解决此问题:尝试按调整传输协议中所述调整协议。
可能的原因:消息太大,以致于占用了过多的带宽。
确认问题的起因:尝试使用较小的消息运行基准测试程序。
解决此问题:
请应用程序开发者对应用程序进行修改以使用消息压缩功能,请参见 Message Queue Developer's Guide for Java Clients。
将消息作为要发送的数据的通知来使用,但使用其他协议来移动数据。
可能的原因:使连接吞吐量变低的可能原因也就是消息传送过程中某个步骤的瓶颈。
确认问题的起因:如果上述任何一条似乎都不是造成连接吞吐量变低的原因,请参见影响性能的因素以了解其他可能的瓶颈,并检查与以下问题相关的症状:
解决此问题:请遵循上述有关疑难解答的各节中所提供的问题解决原则。
症状:
无法为物理目的地创建消息生成方;客户端收到异常。
可能的原因:
可能的原因:物理目的地被配置为仅允许有限数目的生成方。
限制某个物理目的地所支持的生成方 (maxNumProducers ) 数目是避免消息在该物理目的地上堆积的方法之一。
确认问题的起因:检查物理目的地:
imqcmd query dst
(请参见显示有关物理目的地的信息)。输出结果将显示当前的生成方数目以及 maxNumProducers 的值。如果这两个值相同,则说明生成方的数目已达到所配置的限制。如果新的生成方被代理拒绝,代理将返回异常
ResourceAllocationException [C4088]:已达到 JMS 目的地限制
且在代理日志中生成如下条目:
[B4183]:无法将生产方添加到目的地。
解决此问题:增加 maxNumProducers 属性的值(请参见更新物理目的地属性)。
可能的原因:由于访问控制属性文件中的设置,用户未获得创建消息生成方的授权。
确认问题的起因:如果新的生成方被代理拒绝,代理将返回异常
JMSSecurityException [C4076]:客户端没有在目的地上创建生成方的权限
且在代理日志中记录以下条目:
[B2041]:目的地上的生成方被拒绝 [B4051]:禁用 guest。
解决此问题:更改访问控制属性,允许用户生成消息(请参见对物理目的地的访问控制)。
症状:
发送持久性消息时,send 方法不返回,并且客户端发生阻塞。
发送持久性消息时,客户端收到异常。
生成方客户端速度变慢。
可能的原因:
可能的原因:代理上堆满了后备队列,使得消息生成方的执行速度变慢。
堆满后备队列的代理将消息堆积在代理内存中。当物理目的地内存中的消息数或消息字节数达到配置的限制时,代理会尝试根据指定的限制行为来节省内存资源。以下限制行为会使消息生成方速度减慢:
FLOW_CONTROL:代理不会立即确认收到持久性消息(这样就会阻塞生成方客户端)。
REJECT_NEWEST:代理将拒绝新的持久性消息。
同样,如果代理范围的内存(对于所有物理目的地)中消息数或消息字节数达到配置的限制,代理将尝试通过拒绝最新的消息来节省内存资源。另外,如果达到了系统内存限制(由于物理目的地或代理范围限制设置不正确),代理将采取愈加严格的操作来防止内存过载。这些操作包括限制消息生成方。
确认问题的起因:如果某个消息因为达到了配置的消息限制而被代理拒绝,代理将返回异常
JMSException [C4036]:发生服务器错误
且在代理日志中生成以下条目:
[B2011]:存储来自 IMQconn 的 JMS 消息失败。
随后又产生一条消息表明已达到内存限制:
[B4120]:无法在目的地 destName 上存储消息,因为会超出 maxNumMsgs 的容量。
如果超出的消息限制是在物理目的地上,或
[B4024]:已经超出目前系统中的最大消息数,正在拒绝消息。
如果消息限制是代理范围的。
通常,您可以在发生拒绝之前按如下方式检查消息限制情况:
查询物理目的地和代理,并检查其配置的消息限制设置。
使用相应的 imqcmd 命令,监视当前物理目的地或代理(作为一个整体)中的消息数或消息字节数。有关可以监视的度量以及用来获取它们的命令的信息,请参见第 18 章,度量参考。
解决此问题:
修改物理目的地上的(或代理范围的)消息限制,请小心不要超出内存资源。
通常,应该根据每个目的地来管理内存,这样才不会达到代理范围的消息限制。有关详细信息,请参见代理调整。
更改目的地上的限制行为,以便达到消息限制时不会减慢消息的生成,而是丢弃内存中的消息。
例如,您可以指定 REMOVE_OLDEST 和 REMOVE_LOW_PRIORITY 限制行为,这些行为可以删除在内存中堆积的消息(请参见表 15–1)。
可能的原因:代理无法将持久性消息保存到数据存储库中。
如果代理无法访问数据存储库或者无法将持久性消息写入数据存储库,则生成方客户端将受阻。如前所述,如果达到了目的地或代理范围的消息限制,也会发生这种情况。
确认问题的起因:如果代理无法写入数据存储库,它将在代理日志中生成以下条目之一:
[B2011]:存储来自 connectionID 的 JMS 消息失败或 [B4004]:无法持续消息 messageID。
解决此问题:
如果是基于文件的持久性,则尝试增大基于文件的数据存储库的磁盘空间。
如果是符合 JDBC 的数据存储库,则检查基于 JDBC 的持久性是否正确配置(请参见配置持久性数据存储库)。如果是这样,请向数据库管理员咨询,以解决其他数据库问题。
可能的原因:代理的确认超时时间太短。
由于连接太慢或代理反应迟缓(由于 CPU 占用率太高或者内存资源不足导致),代理用于确认收到持久性消息的时间比连接工厂的 imqAckTimeout 属性值所允许的时间要长。
确认问题的起因:如果超出了 imqAckTimeout 值,代理将返回异常
JMSException [C4000]:包确认失败
解决此问题:更改 imqAckTimeout 连接工厂属性的值(请参见可靠性和流控制)。
可能的原因:生成方客户端遇到了 JVM 限制。
确认问题的起因:
查明客户端应用程序是否收到了“内存不足”错误。
使用诸如 freeMemory、maxMemory 和 totalMemory 等运行时环境方法检查 JVM 堆中的可用内存。
解决此问题:调整 JVM(请参见Java 虚拟机调整)。
症状:
消息的生成发生了延迟,或者生成的消息被代理拒绝。
消息到达使用方的时间过长。
代理(或特定目的地)中的消息数或消息字节数随着时间的推移稳定增加。
要查看消息是否在堆积,请检查代理中的消息数或消息字节数如何随时间的推移而改变,并与配置的限制进行比较。首先检查配置的限制:
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 标题下列出的消息数目是否与目的地中的消息数目相同。此标题下的消息已发送到使用方但未得到确认。如果此数目与消息总数相同,则说明代理已发送所有消息,正在等待确认。
解决此问题:请求应用程序开发者帮助调试此问题。
症状:
消息的吞吐量间歇性地下降,然后又恢复正常性能。
可能的原因:
可能的原因:代理的内存资源非常低。
由于目的地和代理限制设置不当,代理采取了越来越严格的措施以防止内存过载,这样就导致代理变得非常迟缓,直到堆积的消息得到清除为止。
确认问题的起因:在代理日志中检查内存低的情况:
[B1089]:内存不足,代理正在尝试释放资源
该情况后面会接有一个描述新内存状态和已用内存总量的条目。另外请检查 JVM 堆中的可用内存:
imqcmd metrics bkr -m cxn
当总 JVM 内存接近 JVM 内存最大值时,可用内存就会很低。
解决此问题:
调整 JVM(请参见Java 虚拟机调整)。
增大系统交换空间。
可能的原因:正在发生 JVM 内存回收(垃圾收集)。
内存回收会定期清扫整个系统,以释放内存。发生此操作时,所有的线程都会阻塞。要释放的内存量以及 JVM 堆的大小越大,因内存回收而导致的延迟就越长。
确认问题的起因:监视计算机上的 CPU 使用率。发生内存回收时,CPU 使用率会下降。
另外,使用以下命令行选项启动代理:
- vmargs -verbose:gc
其标准输出指明发生内存回收的时间。
解决此问题:在多个 CPU 的计算机中,将内存回收设置为并行发生:
-XX:+UseParallelGC=true
可能的原因:JVM 使用实时编译器来提高性能。
确认问题的起因:检查有无其他可能的原因导致此问题。
解决此问题:让系统运行一段时间,性能应该会有所改善。
症状:
使用方未收到生成方发送的消息。
可能的原因:
可能的原因:限制行为导致消息在代理上被删除。
如果目的地内存中的消息数或消息字节数达到了配置限制,代理将尝试节省内存资源。当达到限制时,代理将采用下列三个可配置的行为,从而导致消息丢失:
REMOVE_OLDEST:删除最旧的消息。
REMOVE_LOW_PRIORITY:根据消息的存留期删除优先级最低的消息。
REJECT_NEWEST:拒绝新的持久性消息。
确认问题的起因:检查停用消息队列,如停用消息队列包含消息中所述。具体地说,是使用“消息的数目或者其大小超出目的地限制”中的说明。查找 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"。将出现如下所示的列表:
双击消息可显示该消息的详细信息:
请注意消息的 JMS_SUN_DMQ_UNDELIVERED_REASON 属性值是否为 EXPIRED。
解决此问题:联系应用程序开发者,请他们提高生存时间值。
可能的原因:时钟不同步。
如果时钟之间不同步,则代理对消息生命周期的计算可能有错误,从而导致消息超过它们的到期时间而被删除。
确认问题的起因:在代理日志文件中,查找下列任一消息:B2102、B2103、B2104。这些消息均报告检测到可能的时钟脉冲相位差。
解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。
可能的原因:使用方客户端未能在某个连接上启动消息传送。
除非客户端代码建立了连接,并在该连接上启动了消息传送,否则消息将无法传送。
确认问题的起因:检查客户端代码是否能建立连接并启动消息传送。
解决此问题:重写客户端代码,以建立连接并启动消息传送。
症状:
列出目的地后,发现停用消息队列包含消息。例如,执行如下所示的命令:
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 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_SUN_DMQ_UNDELIVERED_REASON
JMS_SUN_DMQ_UNDELIVERED_COMMENT
JMS_SUN_DMQ_UNDELIVERED_TIMESTAMP
请注意 JMS 标题下面的 JMSDestination 值,以确定消息将停用的目的地。
解决此问题:增加目的地限制。例如:
imqcmd update dst - n MyDest -o maxNumMsgs=1000
可能的原因:代理时钟和生成方时钟不同步。
确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。
在代理日志文件中,查找下列任一消息:B2102、 B2103、B2104。这些消息均报告检测到可能的时钟脉冲相位差。
解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。
可能的原因:消息超时前,使用方未接收到消息。
确认这是否就是问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。
检查目的地中是否有任何使用方。例如:
imqcmd query dst -t q -n MyDest
检查列出的“当前活动使用方数”值。如果有活动使用方,则下面的某一项为真:
使用方的连接暂停。
相对使用方执行速度而言,消息超时时间太短。
解决此问题:请求应用程序开发者提高消息的生存时间值。
可能的原因:相对使用方数目而言,生成方太多。
确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值。如果原因是 REMOVE_OLDEST 或 REMOVE_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
在度量输出中,检查以下值:
Msgs/sec Out:显示代理每秒删除多少条消息。在所有使用方确认收到消息后,代理将删除这些消息,因此,该度量反映了使用率。
Msgs/sec In:显示代理每秒从生成方接收多少条消息。此度量反映了生成率。
由于流控制使生成与使用协调一致,因此请注意生成是否减慢或停止。如果生成减慢或停止,则说明生成方和使用方的处理速度不一致。也可以使用 imqcmd list dst 命令,检查未确认的 (UnAcked) 发送消息的数目。如果未确认的消息数目小于目的地大小,则表明目的地尚有额外的容量,它受到客户端流控制的抑制。
解决此问题:如果生成率始终高于使用率,可以考虑有规律地使用流控制以使系统保持协调一致。此外,使用后面各节的内容,考虑并尝试消除下列可能的因素:
可能的原因:使用方太慢。
确认问题的起因:使用度量来确定生成和使用的速率,如前面“生成方比使用方的速度快”中所述。
解决此问题:
使用如下所示的命令,将目的地限制行为设置为 FLOW_CONTROL:
imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL
使用流控制将生成率降低到使用率,防止消息在代理中堆积。生成方应用程序保留消息,直到目的地可以处理它们,从而降低过期风险。
向应用程序开发者了解生成方是以稳定的速率发送消息,还是周期性成批发送。如果应用程序发送成批消息,请按照下一项中的说明增加目的地限制。
根据消息数和/或字节数增加目的地限制。要更改目的地中的消息数,请输入如下格式的命令:
imqcmd update dst - n destName -t {q|t} -o maxNumMsgs=number
要更改目的地的大小,请输入如下格式的命令:
imqcmd update dst -n destName -t {q|t} -o maxTotalMsgBytes=number
请注意,增加限制会增加代理使用的内存数。如果限制过高,代理可能会耗尽内存,从而无法处理消息。
考虑您是否可以在高负载生成期间接受消息丢失。
可能的原因:客户端不提交消息。
确认问题的起因:与应用程序开发者进行确认以查明应用程序是否使用事务。如果应用程序使用事务,则按如下所示列出活动事务:
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
解决此问题:
使用 imqcmd purge dur 命令清除长期使用方。
重新启动使用方应用程序。
可能的原因:发生意外的代理错误。
确认问题的起因:使用 QBrowser 对消息进行检查,如前面“生成方比使用方的速度快”中所述。如果 JMS_SUN_DMQ_UNDELIVERED_REASON 的值是 ERROR,则说明代理发生错误。
解决此问题:
检查代理日志文件以查找相关错误。
联系 Sun 技术支持以报告代理问题。