2015-12-20 42 views
1

我無法處理來自IBM MQ大消息,並得到下面的錯誤:Spring JMS + IBM MQ:如何設置消息緩衝區大小或等待超時?

JMSCMQ0001:WebSphere MQ的調用與compcode失敗 '1'( 'MQCC_WARNING')的原因 '2080'( 'MQRC_TRUNCATED_MSG_FAILED')

我正在使用DefaultListenerContainer,而不是直接使用IBM MQ Java API類通過MessageConsumer進行消費。我相信通過使用IBM MQ JMS API,您可以在從隊列中檢索消息之前指定特定的選項。但我怎麼用DefaultListenerContainer來做到這一點,是否有我可以爲這些設置的系統屬性?

如果使用IBM MQ JMS API(我不消耗這樣的消息中,粘貼僅供參考):

MQGetMessageOptions mqGetMessageOptions =新MQGetMessageOptions(); mqGetMessageOptions.waitInterval = ipreoProperties.getMqReceiveWaitTime(); mqGetMessageOptions.options = MQC.MQGMO_WAIT | MQC.MQPMO_SYNCPOINT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;

下面是我的Java配置爲IBM MQ連接:

@Bean 
    public CachingConnectionFactory ipreoMQCachingConnectionFactory() { 

     CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(); 

     //Not defining MQQueueConnectionFactory as separate bean as Spring boot's auto-configuration finds two instances 
     //of ConnectionFactory and throws ambiguous implementation exception 
     //One implementation is CachingConnectionFactory and other one would be MQQueueConnectionFactory if defined separately 

     MQQueueConnectionFactory mqConnectionFactory = new MQQueueConnectionFactory(); 

     try { 

      mqConnectionFactory.setHostName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_HOSTNAME)); 
      mqConnectionFactory.setQueueManager(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_QUEUE_MGR)); 
      mqConnectionFactory.setPort(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_PORT, Integer.class)); 
      mqConnectionFactory.setChannel(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_CHANNEL)); 
      //mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT); 

      //Setting connection mode as Client so it doesn't complain for native IBM MQ libraries 
      mqConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT); 

     } catch (JMSException exception) { 
      exception.printStackTrace(); 
     } 

     cachingConnectionFactory.setTargetConnectionFactory(mqConnectionFactory); 

     //Setting session caching size as 10, don't think we need more 
     cachingConnectionFactory.setSessionCacheSize(10); 
     cachingConnectionFactory.setReconnectOnException(true); 

     return cachingConnectionFactory; 
    } 

public DefaultMessageListenerContainer ipreoDealActivityListenerContainer() { 

     DefaultMessageListenerContainer factory = new DefaultMessageListenerContainer(); 
     factory.setConnectionFactory(ipreoMQCachingConnectionFactory()); 
     factory.setDestinationName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_DEAL_QUEUE_NAME)); 
     factory.setMessageListener(ipreoDealActivityListener()); 
     factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE); 

     return factory; 
    } 

@Bean 
    public MessageListener ipreoDealActivityListener() { 
     return new IpreoDealActivityListener(); 
    } 

感謝您的幫助,謝謝。

回答

0

在與隊列管理器的客戶端連接上,可以限制服務器和客戶端上的消息大小。在客戶端限制小於消息大小之前,我已經看到過這個錯誤。

我不知道如何直接在JMS客戶端中設置郵件大小限制,但可以使用客戶端通道定義表。它是一個包含連接到隊列管理器的細節的文件,在隊列管理器上創建,然後複製到客戶端主機。您需要通過在連接工廠發佈setCCDTURL來引用文件(使用CCDT時不需要設置主機,端口和通道,CCDT將指定這些文件)。

在隊列管理器上創建CCDT時,需要在客戶端通道上設置相應的消息大小限制。

服務器端限制在服務器連接通道上設置。

0

在接收緩衝區的JMS客戶端代碼處理中,我們自動處理;理論是JMS應用程序永遠不會收到特定的錯誤。

代碼的第一部分是Java類API,這可能會導致該錯誤。

這些消息實際上有多大?您使用的是什麼級別的JMS客戶端代碼 - 確保它是最新版本。當然是7.5或8版本中的一個。

這個answer也有這方面的一些更多的信息。