Java Mule持久ActiveMQ重新交付策略

Java Mule持久ActiveMQ重新交付策略,java,mule,activemq,retry-logic,Java,Mule,Activemq,Retry Logic,我使用Mule作为ESB解决方案。我有一个队列,从那里我得到消息,并试图向一直失败的服务发出http请求 我在ActiveMQ上配置了RedeliveryPolicy,如下所示: <spring:bean id="retryRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy" name="retryRedeliveryPolicy"> <spring:property

我使用Mule作为ESB解决方案。我有一个队列,从那里我得到消息,并试图向一直失败的服务发出http请求

我在ActiveMQ上配置了RedeliveryPolicy,如下所示:

    <spring:bean id="retryRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy"
        name="retryRedeliveryPolicy">
        <spring:property name="maximumRedeliveries" value="76" />
        <spring:property name="initialRedeliveryDelay" value="300000" />
        <spring:property name="maximumRedeliveryDelay" value="3600000" />
        <spring:property name="useExponentialBackOff" value="true" />
        <spring:property name="backOffMultiplier" value="2" />
        <spring:property name="queue" value="*" />
    </spring:bean>

5分钟后重试。然后10分钟,20,40,60,60,60。。。大约30天

问题是重试逻辑是非持久性的。

比方说,消息重试了2天。我已经部署了新版本的mule应用程序,或者重新启动了服务器。。。在这种情况下,重试逻辑将从5分钟、10分钟……重新开始。。。。因为重试状态由客户端保存在RAM内存中

热以使重新交付政策持续?在我将在2天后重新启动服务器后,它必须再重试1天


我认为一个解决方案可能是将timeToLive设置为72小时。但即使在重启服务器之后。它不会从一开始就每小时重试一次。它将从5分钟开始…

您可以使用JMS消息的JMSXDeliveryCount属性来检查已经重试了多少次。重试时间间隔逻辑应依赖于JMSXDeliveryCount变量

message.getIntProperty(“JMSXDeliveryCount”)


这不是使重新交付策略持久化的方法-它由连接工厂控制,当您重新启动服务器时,工厂将被重置。按照您配置它的方式,它将继续执行您看到的行为,因为您已将useExponentialBackOff设置为true。您可以将其设置为false,以使延迟成为常规量,但这是唯一要做的更改


我认为您设置消息TTL的想法是正确的,至少这将在指定时间后删除消息。JMSXDeliveryCount非常好,但是如果您增加重试之间的延迟,它将在多次尝试后删除,而不是在定义的时间段内删除。

ActiveMQ有一种方法可以执行持久的重新交付,但它不是使用ConnectionFactory上的重新交付策略内置的,该策略用于失败之前的短期重新交付

但是,可以使用ActiveMQ调度程序和延迟消息构建持久的重新交付。有点手动,但可行。在尝试此操作之前,请确保在ActiveMQ中启用schedulerSupport=“true”

JMS属性:“delivery”跟踪重试次数,如果出现问题,catch异常策略会延迟多次重新传递消息。实际延迟由ActiveMQ处理,因此此流可以处理小时、天等延迟,并承受ActiveMQ和Mule的重新启动

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
    xmlns:jms="http://www.mulesoft.org/schema/mule/jms" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata"
    xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">

    <spring:beans>
        <spring:bean name="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
            <spring:property name="maximumRedeliveries" value="0" />
        </spring:bean>

        <spring:bean name="cf"
            class="org.apache.activemq.ActiveMQConnectionFactory">
            <spring:property name="brokerURL" value="tcp://localhost:61616" />
            <spring:property name="redeliveryPolicy" ref="redeliveryPolicy" />
        </spring:bean>
    </spring:beans>

    <jms:activemq-connector name="Active_MQ"
        specification="1.1" brokerURL="tcp://localhost:61616"
        validateConnections="true" doc:name="Active MQ" numberOfConsumers="1"
        maxRedelivery="-1" connectionFactory-ref="cf" />

    <flow name="testFlow">
        <jms:inbound-endpoint queue="IN" connector-ref="Active_MQ"
            doc:name="JMS">
            <jms:transaction action="ALWAYS_BEGIN" />
        </jms:inbound-endpoint>

        <set-property propertyName="delivery"
            value="#[message.inboundProperties['delivery'] or 0]" doc:name="Property" />

        <scripting:component doc:name="Throw Error">
            <scripting:script engine="Groovy"><![CDATA[throw new java.lang.RuntimeException("Error in processing")]]></scripting:script>
        </scripting:component>

        <choice-exception-strategy doc:name="Choice Exception Strategy">
            <catch-exception-strategy doc:name="Catch Exception Strategy"
                when="#[message.outboundProperties['delivery'] &lt; 5]">
                <logger level="ERROR"
                    message="Retry once more count #[message.outboundProperties['delivery']]"
                    doc:name="Logger" />

                <set-property propertyName="AMQ_SCHEDULED_DELAY" value="3000"
                    doc:name="Property" />
                <set-property propertyName="delivery"
                    value="#[message.outboundProperties['delivery'] + 1]" doc:name="Property" />
                <jms:outbound-endpoint queue="IN"
                    connector-ref="Active_MQ" doc:name="JMS">
                    <jms:transaction action="ALWAYS_JOIN" />
                </jms:outbound-endpoint>

            </catch-exception-strategy>

            <rollback-exception-strategy doc:name="Rollback Exception Strategy">
                <logger level="ERROR" message="Giving up retry. Do whatever needed here." doc:name="Logger" />
            </rollback-exception-strategy>
        </choice-exception-strategy>
    </flow>
</mule>