2014-11-25 206 views
0

我有一個Websphere MQ和一個Java應用程序接收來自它的消息。如果在我的應用程序中引發任何異常,我想重新發送系統。我使用spring事務管理器,但問題是如果消息在我的應用程序中導致異常,應用程序正在嘗試重新發送相同的消息。如果有一些(2,3等)不成功的重新交付嘗試,我可以在隊列末尾放置一個破碎的信息嗎?Websphere MQ消息傳遞

這裏是我的Spring配置:

<bean id="mqMessageListener" class="ru.mos.notification.controller.MQNotificationListener"> 
    <property name="mqwsUrl" value="${mqws.url}" /> 
    <property name="mqwsSoapAction" value="${mqws.soapAction}" /> 
    <property name="mqwsSoapStart" value="${mqws.soapStart}" /> 
    <property name="mqwsSoapEnd" value="${mqws.soapEnd}" /> 
</bean> 

<bean id="mqQueueConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory"> 
    <property name="hostName" value="${mq.hostName}" /> 
    <property name="port" value="${mq.port}" /> 
    <property name="queueManager" value="${mq.queueManager}" /> 
    <property name="transportType" value="1" /> 
    <property name="channel" value="${mq.channel}" /> 
</bean> 

<bean id="jmsConnectionFactory" 
    class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter"> 
    <property name="targetConnectionFactory" ref="mqQueueConnectionFactory" /> 
    <property name="username" value="${mq.username}" /> 
    <property name="password" value="${mq.password}" /> 
</bean> 

<bean 
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
    <property name="destinationName" value="${mq.destinationName}" /> 
    <property name="destinationResolver"> 
     <bean 
      class="org.springframework.jms.support.destination.DynamicDestinationResolver" /> 
    </property> 
    <property name="sessionAcknowledgeModeName" value="AUTO_ACKNOWLEDGE" /> 
    <property name="sessionTransacted" value="true" /> 
    <property name="messageListener" ref="mqMessageListener" /> 
    <property name="transactionManager" ref="transactionManager"/> 
    <property name="connectionFactory" ref="jmsConnectionFactory" /> 
</bean> 

這裏的onMessage方法的代碼:

public void onMessage(Message mess) { 
    try { 
     if (mess instanceof TextMessage) { 
      String m = ((TextMessage) mess).getText(); 
      logger.info("MQNotificationListener.onMessage TextMessage=" + m); 

      Properties prop = new Properties(); 
      prop.setProperty("SOAPAction", mqwsSoapAction); 

      HTTPSend.sendHTTP(mqwsUrl, mqwsSoapStart + m + mqwsSoapEnd, 
        "UTF-8", prop); 

      String response = HTTPSend.sendHTTP(mqwsUrl, mqwsSoapStart + m 
        + mqwsSoapEnd, "UTF-8", prop); 

      checkResponse(response); 

     } else if (mess instanceof BytesMessage) { 
      /* 
      * byte[] body = new byte[(int) ((BytesMessage) 
      * mess).getBodyLength()]; ((BytesMessage) 
      * mess).readBytes(body); 
      * 
      * String enc = Utils.getProperty(Utils.FP_MIGRATION, 
      * "mqrec.encoding"); 
      * 
      * text = new String(body, enc); 
      */ 
      logger.info("MQMessageListener.onMessage BytesMessage"); 

     } else { 
      logger.info("MQMessageListener.onMessage other"); 
     } 
    } catch (Exception e) { 
     logger.error(
       "MQMessageListener.onMessage Exception: " + e.getMessage(), 
       e); 
     throw JmsUtils.convertJmsAccessException(new JMSException(null)); 
    } 
} 

回答

0

隊列先進先出的基礎上運作,先入先出。

所以兩個選項

  • 到應用程序將消息路由別的地方內。
  • 指定消息的優先級較低,然後確保按優先級順序關閉消費拉取消息。

這兩個選項都需要消費者與製作人合作。

+0

第二個選項。它是在Websphere方面配置的,還是我應該以某種方式降低應用程序中的消息優先級? – 2014-11-26 07:59:12

+0

您可以在應用程序中改變優先級時,它被送到 – Calanais 2014-12-01 09:44:06

+0

另一種選擇是使用使用BOTHRESH和BOQNAME隊列配置參數WMQ的退出資源,其中BOTHRESH定義你會嘗試多少次消費的消息和參數BOQNAME後確定QUEUE的名稱,表示您的郵件將被重新傳遞。在這種情況下,您可以使用DLQ QUEUE,您可以在一段時間後將消息移動到主QUEUE,或者將主QUEUE作爲DLQ QUEUE使消息在消費者中旋轉。 – 2017-05-12 15:23:30