问题
I am working on below configuration for messaging using Spring and Webphere MQ.
I have a requirement of implementing retrying logic for a scenario, where I receive a message from the queue and put the message data on to a Elastic search server (search server is non transactional), if the search server is down I have to rollback the message on to the queue again and process the message after some interval of time(for example: 30 seconds) . this retry has to be done for 5 times. after 5 times the message has to be put on a Dead letter queue .we are using Tomcat as the server.
we are using spring integration jms:message-driven-channel-adapter for message receiving
How can I implement this behavior with spring and Websphere MQ?
I have crawled across many sites, and I could find support for Active MQ but not for IBM MQ.
<bean id="mqConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName">
<value>${queue_hostname}</value>
</property>
<property name="port">
<value>${queue_port}</value>
</property>
<property name="queueManager">
<value>${queue_manager}</value>
</property>
<property name="transportType">
<value>1</value>
</property>
</bean>
<!-- JMS Queue Connection Factory -->
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory102">
<property name="targetConnectionFactory">
<ref bean="mqConnectionFactory" />
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
</bean>
<!-- JMS Destination Resolver -->
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.DynamicDestinationResolver">
</bean>
<!-- JMS Queue Template -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsQueueConnectionFactory" />
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver" />
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
<property name="receiveTimeout">
<value>20000</value>
</property>
</bean>
回答1:
There is nothing in the JMS spec about delayed redeliveries. Some brokers have a custom mechanism/policy to implement it; you'll have to look at the broker documentation.
As has been said before, you can use the delivery count header to give up after some number of retries.
EDIT
In response to your comment below...
Only if you are using a version of MQ that supports JMS 2.0 - it looks like you are using a very old version requiring JmsTemplate102
. 1.0.2 is ancient; 1.1 has been out for years; Spring has supported JMS 2.0 for a nearly 3 years. If you have a JMS 2.0 broker (and client library), set the deliveryDelay on a JmsTemplate bean. Then, configure the outbound channel adapter to use that template via the jms-template
property.
In order to get visibility to the redelivery count, either pass the whole message into your service or, with a POJO method, configure it to get that header...
public MyReply process(@Payload MyObject foo,
@Header("JMSXRedeliveryCount") int redeliveryCOunt) {
...
}
Again, this is a JMS 2.0 feature (the header) although some brokers provide it in 1.1.
回答2:
IBM MQ doesn't have the delay redelivery but one option would be to consider using the JMS2.0 concept of Delayed Delivery. This doesn't set the redelivered flag so won't engage any backout logic but it would implemented the timed behaviour.
For example when the message couldn't be processed it could be requeued by the application with a delay. This won't be then seen again for say 5 minutes. The application would probably have to mark the message with a counter. Both could be done under transacted session to achieve
来源:https://stackoverflow.com/questions/34342579/implementing-retry-logic-in-ibm-websphere-mq-with-spring