2016-12-28 38 views
2

當我嘗試發送JMS消息到外部隊列 ,可以用如下錯誤而失敗MQRC_UNKNOWN_ALIAS_BASE_Q使用彈簧JmsTemplate的時候發送消息

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的動態目標解析器,我可以發送消息

this.jmsTemplate.convertAndSend(「TESTQUEUE」, message.getJson());

回答

3

在這種情況下,當一個程序工作,一個沒有區別是兩個程序已解析爲不同的隊列名稱。要弄清楚什麼是錯誤的,需要了解名稱是如何解決的。有兩種可能性,其中2082: MQRC_UNKNOWN_ALIAS_BASE_Q結果:

  1. 別名隊列的TARGQ屬性指向一個不存在的隊列。
  2. 別名隊列是指非本地羣集隊列。

在第一種情況下,別名隊列在本地隊列上定義,但定義在某些方面有缺陷。通常是因爲本地隊列名稱拼寫錯誤。結果是TARGQ沒有本地的東西可以解決。這很容易通過簡單的檢查或使用amqsput或將消息放入隊列的任何其他樣本進行診斷。

這可以在一個實例中工作,而不是其他描述的唯一方式是,一個應用程序解析爲別名隊列,另一個不解析。例如,兩個應用程序中的一個指定了一個非本地QMgr名稱,並且該消息直接放入傳輸隊列,而另一個應用程序通過解析爲已破壞的別名來達到死衚衕。

第二種情況是別名解析爲非本地羣集隊列但調用程序已將本地QMgr名稱指定爲目標的一部分。理解這種情況的關鍵是,與可以重新映射QMgr名稱的QRemote不同,QAlias不會更改調用應用程序指定的QMgr名稱。由於不應提供QMgr名稱來移除羣集隊列,因此在此處提供非空字符串會中斷解析。

這是爲什麼......打開聚簇隊列時,應用程序不指定QMgr名稱,MQ決定要發送到哪個實例。名稱解析機制首先在本地查找,如果它找到一個羣集隊列,它將使用CLWLUSEQ屬性來決定是否偏好本地實例通過羣集實例。但如果它發現它是羣集隊列的別名,它將使用TARGQ名稱重新驅動解析。如果本地QMgr名稱已被指定爲完全限定目標地址的一部分,並且沒有與TARGQ相匹配的本地隊列實例,則在此時無法解決該問題,並且解決方法失敗。要在羣集隊列上成功使用別名,因此需要調用程序而不是指定QMgr名稱。

因此,這兩個程序都解析爲不同的隊列名稱。你相信當行爲表明他們不可能需要處理以進一步診斷時,他們會解決同名問題。

要做的最好的事情是使用一個已知好的代碼段,其分辨率是毫不含糊的。 amqsput示例很好,但您真正需要測試的是允許指定要連接的QMgr名稱和目標地址的QMgr名稱的程序,例如SupportPac MA01的Q程序。通過不同地指定目標中的本地QMgr名稱或將其保留爲空來重新創建錯誤,您將能夠辨別它發生故障的情況,然後相應地修改代碼。

0

正如Rob提到的那樣,如果它是一個集羣隊列,那麼不要指定隊列管理器。

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

這個配置適用於我。