Ibm mq 使用spring JmsTemplate发送消息时使用MQRC_UNKNOWN_别名_BASE_Q

Ibm mq 使用spring JmsTemplate发送消息时使用MQRC_UNKNOWN_别名_BASE_Q,ibm-mq,spring-jms,Ibm Mq,Spring Jms,当我尝试将JMS消息发送到外部队列时 它失败了,错误如下 error occured while sending the message :JMSWMQ2008: Failed to open MQ queue 'TESTQUEUE'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2082' (

当我尝试将JMS消息发送到外部队列时 它失败了,错误如下

error occured while sending the message :JMSWMQ2008: Failed to open MQ queue 'TESTQUEUE'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2082' ('MQRC_UNKNOWN_ALIAS_BASE_Q').
Jms模板声明

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="cachedJmsQueueConnectionFactory" />
        <property name="pubSubDomain" value="false" />
        <property name="receiveTimeout" value="2000" />
    </bean>

<bean id="testQueue" class="com.ibm.mq.jms.MQQueue">
        <property name="baseQueueManagerName" value="${test.qmgrName}" />
        <property name="baseQueueName" value="${test.queue}" />
    </bean>

this.jmsTemplate.convertAndSend(getDestinationBean("testQueue"),
                        message.getJson());

这个.jmsTemplate.convertAndSend(getDestinationBean(“testQueue”),
message.getJson());
但如果将动态目标解析器与jmsTemplate一起使用,则可以发送消息

这个.jmsTemplate.convertAndSend(“TESTQUEUE”,
message.getJson())

在这种情况下,当一个程序工作而另一个程序不工作时,区别在于两个程序已解析为不同的队列名称。要想找出问题所在,需要了解名称的解析方式。
2082:MQRC\u UNKNOWN\u ALIAS\u BASE\u Q
结果有两种可能:

  • 别名队列的
    TARGQ
    属性指向一个不存在的队列
  • 别名队列是指非本地群集队列
  • 在第一种情况下,别名队列是在本地队列上定义的,但该定义在某些方面存在缺陷。这通常是因为本地队列名称拼写错误。结果是,
    TARGQ
    没有它可以解析的本地内容。通过简单的检查或使用
    amqsput
    或将消息放入队列的任何其他样本,就可以很容易地进行诊断

    这在一个实例中而不是在另一个实例中工作的唯一方法是一个应用解析为别名队列,而另一个不解析。例如,这两个应用程序中的一个指定了非本地QMgr名称,消息直接放入传输队列,而另一个应用程序则通过解析断开的别名而陷入死胡同

    第二种情况是别名解析为非本地群集队列,但调用程序已将本地QMgr名称指定为目标的一部分。理解这种情况的关键是,与可以重新映射QMgr名称的QRemote不同,QAlias不会更改调用应用程序指定的QMgr名称。由于不应提供QMgr名称来解析集群队列,因此在此处提供非空字符串会中断解析

    这就是为什么…当打开集群队列时,应用程序不指定QMgr名称,而MQ决定向哪个实例发送。名称解析机制首先在本地查找,如果它找到集群队列,它将使用
    CLWLUSEQ
    属性来决定是否首选本地实例而不是集群实例。但是,如果它发现的是集群队列上的别名,它将使用
    TARGQ
    名称重新驱动解析。如果已将本地QMgr名称指定为完全限定的目标地址的一部分,并且没有与
    TARGQ
    匹配的本地队列实例,则此时无法解析该名称,解析将失败。因此,要在集群队列上成功使用别名,调用程序需要不指定QMgr名称

    因此,两个程序都解析为不同的队列名称。当行为表明它们可能无法解析时,您认为它们解析为相同的名称,需要进一步诊断


    最好的办法是使用一段已知的好代码,它的解析是明确的。
    amqsput
    示例很好,但您真正需要测试的是一个程序,它允许您指定要连接到的QMgr名称和目标地址的QMgr名称,例如来自的Q程序。通过在目标中以各种方式指定本地QMgr名称或将其保留为空来重新创建错误,您将能够识别失败的情况,然后相应地修改代码。

    如Rob所述,如果是群集队列,则不指定队列管理器

    <bean id="testInQueue" class="com.ibm.mq.jms.MQQueue">
       <property name="baseQueueName" value="${test.queue}" />
    </bean>
    
    
    
    这个配置对我有用