使用CCDT和Spring Boot JMSTemplate与IBM MQ集群连接时的MQRC_UNKNOWN_ALIAS_BASE_Q

时间:2019-01-29 14:57:00

标签: spring-boot ibm-mq spring-jms jmstemplate

我有一个Spring Boot应用程序,它使用JMSListener + IBMConnectionFactory + CCDT连接IBM MQ集群。

A设置以下连接属性: -指向生成的ccdt文件的网址 -用户名(由于测试环境,不需要密码) -未定义queuemanager名称-由于这是集群的任务,因此,一些google结果(包括多个stackoverflow的结果)表明,在我的情况下,qmgr必须设置为空字符串。

当我的Spring Boot JMSListener尝试连接到队列时,发生以下MQRC_UNKNOWN_ALIAS_BASE_Q错误:

2019-01-29 11:05:00.329 WARN  [thread:DefaultMessageListenerContainer-44][class:org.springframework.jms.listener.DefaultMessageListenerContainer:892] - Setup of JMS message listener invoker failed for destination 'MY.Q.ALIAS' - trying to recover. Cause: JMSWMQ2008: Failed to open MQ queue 'MY.Q.ALIAS'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2082' ('MQRC_UNKNOWN_ALIAS_BASE_Q').
com.ibm.msg.client.jms.DetailedInvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'MY.Q.ALIAS'.
        at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:513)
        at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)

在MQ错误日志中,我看到以下内容:

01/29/2019 03:08:05 PM - Process(27185.478) User(mqm) Program(amqrmppa)
                    Host(myhost) Installation(Installation1)
                    VRMF(9.0.0.5) QMgr(MyQMGR)

AMQ9999: Channel 'MyCHL' to host 'MyIP' ended abnormally.

EXPLANATION:
The channel program running under process ID 27185 for channel 'MyCHL'
ended abnormally. The host name is 'MyIP'; in some cases the host name
cannot be determined and so is shown as '????'.
ACTION:
Look at previous error messages for the channel program in the error logs to
determine the cause of the failure. Note that this message can be excluded
completely or suppressed by tuning the "ExcludeMessage" or "SuppressMessage"
attributes under the "QMErrorLog" stanza in qm.ini. Further information can be
found in the System Administration Guide.
----- amqrmrsa.c : 938 --------------------------------------------------------
01/29/2019 03:15:14 PM - Process(27185.498) User(mqm) Program(amqrmppa)
                    Host(myhost) Installation(Installation1)
                    VRMF(9.0.0.5) QMgr(MyQMGR)

AMQ9209: Connection to host 'MyIP' for channel 'MyCHL' closed.

EXPLANATION:
An error occurred receiving data from 'MyIP' over TCP/IP.  The connection
to the remote host has unexpectedly terminated.

The channel name is 'MyCHL'; in some cases it cannot be determined and so
is shown as '????'.
ACTION:
Tell the systems administrator.

由于MQ错误日志包含 QMgr(MyQMGR)(我未在连接属性中设置的 MyQMGR 值),因此假设路由似乎很好:MQ集群确定了要使用的qmgr。

别名存在并指向现有的q。引导目标q和别名通过CLUSTER(clustname)命令添加到集群。

有什么问题吗?

1 个答案:

答案 0 :(得分:3)

简短回答

  • MQ群集用于使用者应用程序以查找从中获取消息的队列。
  • MQ群集 在生产者应用程序将消息定向到目的地时使用。

进一步阅读

在发送消息时使用集群,以帮助提供负载平衡和集群队列的多个实例。在某些情况下,人们通过具有两个队列实例并仅保留一个PUT(ENABLED)来将其用于热/冷故障转移。

如果应用程序是将消息放入群集队列的生产者,则仅需要将其连接到群集中的队列管理器并具有放入该群集队列的权限。基于多种不同的MQ可以处理将消息发送到何处。


在v7.1之前,只有两种方法可以提供对远程集群队列的访问:

  1. 使用QALIAS

    • 定义本地QALIAS,该本地QALIAS将TARGET设置为集群队列名称

      请注意,QALIAS本身并不需要集群。

    • 已授予放到本地SYSTEM.CLUSTER.TRANSMIT.QUEUE的权限。
  2. 提供对ClusterQueueAccessControl=RQMName进行PUT的权限。

第一个选项允许为群集中的特定群集队列授予对应用程序的粒度访问。第二个选项允许应用程序放置在集群中的任何已排队队列中。

在7.1上,IBM添加了一个新的可选行为,在Security的{​​{1}}节中,该设置为qm.ini。如果启用了此功能(这不是默认设置),则实际上可以为应用程序提供直接将其PUT到远程群集队列的权限,而无需本地QALIAS


不是集群是在消耗一些应用程序,例如您的JMSListener示例。

将要从任何QLOCAL(无论是否集群)使用的应用程序必须连接到定义了QLOCAL的队列管理器。

如果存在QLOCAL集群PUT(ENABLED)的多个实例的情况,则需要确保您的使用者直接连接到实例所在的每个队列管理器。


根据您的评论,您会拥有一个CCDT,其条目如下:

CHANNEL('MyCHL') CHLTYPE(CLNTCONN) QMNAME('MyQMGR') CONNAME('node1url(port1),node2url(port2)')

如果有两个不同的队列管理器在node1url(port1)node2url(port2)上侦听不同的队列管理器名称,那么从应用程序方面,您可以采用不同的方式来完成此任务。

当您指定要连接到应用程序的QMNAME时,除非满足以下条件之一,否则该名称将与您连接的队列管理器相匹配:

  1. 如果您指定*MyQMGR,它将找到一个带有QMNAME('MyQMGR')的通道并选择一个并连接,并且不会强制要求远程队列管理器名称必须匹配。
  2. 如果CCDT中的QNAME('')设置为NULL,那么在您的应用中,您可以指定一个空的队列管理器名称或仅一个空格,它将在CCDT中找到此条目,而不会强制远程队列管理器名称必须匹配。
  3. 在您的应用程序中,将队列管理器名称指定为*,MQ将使用CCDT中的任何通道,并且不会强制要求远程队列管理器名称必须匹配。

CCDT的一个限制是频道名称在CCDT中必须唯一。即使QMNAME有所不同,您也不能使用相同的频道名称输入第二个条目。

连接时,您用两个CONNAME击中条目并连接到第一个IP(port),如果在连接时第一个是第二个IP(port)不可用,MQ将尝试第二个,或者如果您已连接并启用了RECONNECT,然后第一个断开,则MQ将尝试连接到第一个然后第二个。

如果您想让两个集群队列PUT(ENABLED)都接收流量,那么您希望能够专门连接到两个队列管理器中的每个队列以读取这些队列。

我建议您在每个队列管理器上添加一个具有不同QM特定名称的新通道,该名称也不同于现有名称,如下所示:

CHANNEL('MyCHL1') CHLTYPE(CLNTCONN) QMNAME('MyQMGR1') CONNAME('node1url(port1)')
CHANNEL('MyCHL2') CHLTYPE(CLNTCONN) QMNAME('MyQMGR2') CONNAME('node2url(port2)')

这将是现有条目的补充。

对于放置组件,您可以继续使用可以连接到任一队列管理器的通道。

对于获取组件,您至少可以配置其中两个,一个组件使用新的特定于队列管理器的CCDT条目连接到每个队列管理器,这样就消耗了两个队列。