2014-11-25 161 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