Websphere MQ Cluster Workload Balancing:消息进入死信队列

时间:2015-08-19 15:14:52

标签: ibm-mq

我创建了一个包含3个QMgrs的WMQ群集。 2个完整存储库和1个部分存储库。这是mqsc使用的:

crtmqm GW
strmqm GW
runmqsc GW
alter qmgr deadq('SYSTEM.DEAD.LETTER.QUEUE')
define listener(gw.listener) trptype(TCP) port(1416) ipaddr(xx.xx.xx.xx)
start listener(gw.listener)
define channel(SYSTEM.ADMIN.SVRCONN) chltype(svrconn)
ALTER QMGR CHLAUTH(DISABLED)
end

runmqsc QM01
alter qmgr repos('DEVELOPMENT.CLUSTER')
end

runmqsc QM02
alter qmgr repos('DEVELOPMENT.CLUSTER')
end

runmqsc QM01
define chl(to.QM01) chltype(clusrcvr) trptype(tcp) +
       conname('xx.xx.xx.xx(1414)') cluster(DEVELOPMENT.CLUSTER) 
end

runmqsc QM02
define chl(to.QM02) chltype(clusrcvr) trptype(tcp) +
       conname('xx.xx.xx.xx(1415)') cluster(DEVELOPMENT.CLUSTER) 
end

runmqsc GW
define chl(to.GW) chltype(clusrcvr) trptype(tcp) +
       conname('xx.xx.xx.xx(1416)') cluster(DEVELOPMENT.CLUSTER) 
end

runmqsc QM01
DEFINE CHANNEL(TO.QM02) CHLTYPE(CLUSSDR) TRPTYPE(TCP) +
       CONNAME('xx.xx.xx.xx(1415)') CLUSTER(DEVELOPMENT.CLUSTER)
end

runmqsc QM02
DEFINE CHANNEL(TO.QM01) CHLTYPE(CLUSSDR) TRPTYPE(TCP) +
       CONNAME('xx.xx.xx.xx(1414)') CLUSTER(DEVELOPMENT.CLUSTER)
end

runmqsc GW
DEFINE CHANNEL(TO.QM01) CHLTYPE(CLUSSDR) TRPTYPE(TCP) +
       CONNAME('xx.xx.xx.xx(1414)') CLUSTER(DEVELOPMENT.CLUSTER)
DEFINE CHANNEL(TO.QM02) CHLTYPE(CLUSSDR) TRPTYPE(TCP) +
       CONNAME('xx.xx.xx.xx(1415)') CLUSTER(DEVELOPMENT.CLUSTER)
end

runmqsc QM02
define qlocal('BACKUP') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('PROVIDER') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('RESPONSE') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('STORE') CLUSTER(DEVELOPMENT.CLUSTER)
REFRESH CLUSTER(DEVELOPMENT.CLUSTER) REPOS(YES) 
end

runmqsc QM01
define qlocal('BACKUP') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('PROVIDER') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('RESPONSE') CLUSTER(DEVELOPMENT.CLUSTER)
define qlocal('STORE') CLUSTER(DEVELOPMENT.CLUSTER)
REFRESH CLUSTER(DEVELOPMENT.CLUSTER) REPOS(YES)
end

现在我在队列GW上向QMgr PROVIDER发送消息。请注意GW不会托管此队列。它由QM01QM02

托管
amqsput PROVIDER GW

可悲的是,所有消息都将进入QMgr GW的死信队列。

请帮助解决这个问题。任何调试建议都会有所帮助。

1 个答案:

答案 0 :(得分:2)

这里有几个可能的问题。

通道没有相同的定义。一些具有混合大小写的名称,另一些具有全部大写名称。如果您指望缺少引号以确保它们全部由QMgr折叠为大写,则此可能有效。但是,显然已经编辑了命令,至少就CONNAME值而言,所以我不假设结果对象匹配。

创建群集后,您是否检查过所有频道都显示为AUTO-EXPLICIT?这就是您知道群集已正确启动的方式。

REFRESH CLUSTER命令也可能导致中断。定义新对象时不需要这样做,实际上是非常具有破坏性的。它等待重​​新启动的通道,并且在您运行该命令的时间点,用于通告新对象的命令已发送到存储库但未返回。 REFRESH CLUSTER然后请求通道停止,可能是在批处理中间,为群集排队命令以删除刚刚收到但尚未回复的信息,然后向群集发送新命令以通告对象它刚刚删除。如果这听起来令人困惑,请考虑存储库中的集群命令服务器的感受。

从队列定义脚本中删除REFRESH CLUSTER命令。

一旦确定通道已全部前进到AUTO-EXPLICIT并删除REFRESH CLUSTER,您就可以开始实际的调试了。在这些情况下,查看死消息的DLQ标头以找出列出的原因代码确实很有帮助。这通常提供足够的信息来发现问题。您还可以启用各种QMgr诊断事件并使用其中一个事件查看工具查看它们,或查看频道两端QMgrs上的错误日志。

这些下一个建议与您的诊断无关,除了使用最佳实践构建的QMgr通常不易出错且更容易调试。这是一些未经请求的MQ集群最佳实践建议。

  • 放弃TO.[QMGR]频道名称!请改为使用[cluster].[qmgr]名称,例如DEVCLUS.QM01。这可确保您始终拥有专用于每个群集的通道,即使您有重叠的群集也是如此。但是,它确实意味着群集名称中不能包含.,并且必须是< 10个字符。
  • 对于不是完整存储库的事物,只为其中一个存储库定义显式CLUSSDR。如果您拥有两个以上的存储库(例如在迁移期间),集群成员将能够以这种方式找到它。
  • 始终在定义中使用引号。如果您在获取某些内容时遇到问题,那么只有一种可能解释的定义是较短的解决方法。
  • 在定义新的群集通道时,让通道有时间结算,并验证它是否已启动并进入正确的状态。
  • 使用AMQSPUT打开新定义的远程托管群集队列以进行输出,但不实际向其发送消息。确保在打开期间没有错误(即队列解析),然后确保群集通道已启动。 然后 执行amqsput并发送消息。
  • REFRESH CLUSTER是用于部分存储库的命令,而RESET CLUSTER是要在完整存储库上使用的命令。在这种情况下,命令使用不当并且在错误类型的群集节点上。期待问题。
  • 希望在现实生活中,完整的存储库QMgrs上没有托管应用程序队列。您可以为群集执行的最好的事情是在专用QMgrs上托管完整的存储库 - 即使这些是与应用程序QMgrs在同一主机上的额外QMgrs。将它们分开可确保集群操作流量和应用程序流量不会遍历相同的通道。它还可以在应用程序QMgrs之前修补或升级存储库。