有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用spring在Ibm Websphere MQ中实现重试逻辑

我正在使用Spring和WebSphere MQ进行以下消息传递配置

我需要为场景实现重试逻辑,在该场景中,我从队列接收消息,并将消息数据放在弹性搜索服务器上(搜索服务器是非事务性的),如果搜索服务器关闭,我必须再次将消息回滚到队列中,并在一段时间间隔(例如:30秒)后处理消息。此重试必须进行5次。5次之后,必须将消息放入死信队列。我们使用Tomcat作为服务器

我们正在使用SpringIntegrationJMS:消息驱动的通道适配器来接收消息

如何使用spring和Websphere MQ实现此行为

我已经爬过许多站点,我可以找到对活动MQ的支持,但不支持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) 个答案

  1. # 1 楼答案

    IBM MQ没有延迟重发,但有一种选择是考虑使用JMS2。0 Delayed Delivery的概念。这不会设置“重新交付”标志,因此不会使用任何回退逻辑,但会实现定时行为

    例如,当消息无法处理时,应用程序可能会延迟重新查询消息。这将在5分钟内不再被看到。应用程序可能必须用计数器标记消息。这两种方法都可以在事务处理会话下实现

  2. # 2 楼答案

    JMS规范中没有关于延迟重新交付的内容。一些经纪人有一个定制的机制/政策来实施它;你得看看经纪人的文件

    如前所述,您可以使用delivery count头在重试若干次后放弃

    编辑

    作为对你下面评论的回应

    仅当您使用的是支持JMS 2.0的MQ版本时——看起来您使用的是需要JmsTemplate102的非常旧的版本。1.0.2是古老的;1.1已退出多年;Spring支持JMS 2.0已有近3年的历史。如果您有一个JMS 2.0代理(和客户端库),请设置deliveryDelay on a JmsTemplate bean。然后,通过jms-template属性将出站通道适配器配置为使用该模板

    为了获得对重新交付计数的可见性,可以将整个消息传递到您的服务中,或者使用POJO方法将其配置为获取该标头

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

    同样,这是一个JMS 2.0特性(标题),尽管有些代理在1.1中提供了它