我创建了一个包含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
不会托管此队列。它由QM01
和QM02
amqsput PROVIDER GW
可悲的是,所有消息都将进入QMgr GW
的死信队列。
请帮助解决这个问题。任何调试建议都会有所帮助。
答案 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
是要在完整存储库上使用的命令。在这种情况下,命令使用不当并且在错误类型的群集节点上。期待问题。