使用Spring在IBM WebSphere MQ中实现重试逻辑

3
我正在使用Spring和WebSphere MQ实现以下消息配置。在一个场景中,我需要实现重试逻辑:当我从队列接收一条消息并将消息数据放到Elasticsearch服务器上(搜索服务器是非事务性的),如果搜索服务器不可用,我必须将该消息回滚到队列上,并在一段时间后再次处理该消息(例如30秒)。这个重试过程要进行5次。5次后,消息必须被放到死信队列中。我们使用Tomcat作为服务器。我们使用Spring Integration jms:message-driven-channel-adapter来接收消息。
如何使用Spring和WebSphere MQ实现这个行为呢?
我已经查遍了许多网站,发现有关ActiveMQ的支持,但没有关于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>

2
我认为你可以在这里找到答案:https://dev59.com/OWPVa4cB1Zd3GeqP8btk。 - Pat B
@PatB 谢谢你,Pat。那帮了我。 - ravinder reddy
2个回答

1

JMS规范中没有关于延迟重发的内容。一些代理有自定义的机制/策略来实现它;您需要查看代理文档。

正如之前所说,您可以使用传递计数标头,在一定次数的重试后放弃。

编辑

针对下面的评论...

只有当您使用支持JMS 2.0的MQ版本时才能这样做 - 看起来您正在使用需要JmsTemplate102的非常旧的版本。1.0.2是古老的;1.1已经发布多年;Spring已经支持JMS 2.0将近3年。如果您有一个JMS 2.0代理(和客户端库),请在JmsTemplate bean上设置deliveryDelay。然后,通过jms-template属性配置出站通道适配器以使用该模板。

为了获得重传计数的可见性,要么将整个消息传递到您的服务中,要么使用POJO方法将其配置为获取该标头...

public MyReply process(@Payload MyObject foo,
              @Header("JMSXRedeliveryCount") int redeliveryCOunt) {
    ...
}

需要注意的是,这是JMS 2.0的特性(指头信息),尽管一些代理商也在1.1版本中提供了该功能。


我们能否在Spring Integration出站通道适配器中添加下面所回答的延迟交付?关于交付计数标头,我如何在调用了入站适配器->激活器->Spring Bean顺序的Spring Bean中获取计数值? - ravinder reddy
谢谢您的快速回复Russel。那帮了我很多。 - ravinder reddy

1
IBM MQ没有延迟重传,但可以考虑使用JMS2.0的“延迟投递”概念。这不会设置重传标志,因此不会触发任何回退逻辑,但它会实现定时行为。
例如,当应用程序无法处理消息时,可以使用延迟重新排队。然后,在5分钟内不会再次看到该消息。应用程序可能需要使用计数器标记消息。两者都可以在事务会话下完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接