Постоянный Mule ActiveMQ RedeliveryPolicy

Я использую Mule в качестве решения ESB. У меня есть очередь, откуда я получаю сообщения и пытаюсь сделать http-запрос к сервису, который постоянно терпит неудачу.

Я настроил RedeliveryPolicy на ActiveMQ следующим образом:

    <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... примерно на 3 дня

Проблема в том, что логика Retry не является постоянной.

Допустим, сообщение было повторено в течение 2 дней. И я развернул новую версию приложения mule, или перезапустил сервер... В этом случае логика повторного запуска будет начинаться заново с 5 минут, 10 минут.... Поскольку состояние повторения сохраняется в оперативной памяти Клиентом.

Горячий, чтобы сделать RedeliveryPolicy настойчивым? Он должен продолжать повторную попытку еще 1 день после того, как я перезапущу сервер через 2 дня.

Я думаю, что одним из решений может быть установка timeToLive на 72 часа для сообщения. Но даже после перезапуска сервера. Он не будет повторяться каждый час с начала. Это начнется с 5 минут...

3 ответа

ActiveMQ имеет способ выполнять постоянную повторную доставку, но он не встроен с использованием RedeliveryPolicy в ConnectionFactory, который предназначен для коротких периодов повторной доставки до сбоя.

Постоянная повторная доставка может быть построена с использованием планировщика ActiveMQ и задержанных сообщений. Немного ручной, но выполнимый. Убедитесь, что вы включили schedulerSupport="true" в ActiveMQ, прежде чем пытаться это сделать.

Свойство JMS: "delivery" отслеживает количество повторных попыток, и если что-то идет не так, стратегия исключения исключений повторно доставляет сообщение несколько раз с задержкой. Фактическая задержка обрабатывается 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>

Вы можете использовать свойство JMSXDeliveryCount сообщения JMS, чтобы проверить, сколько раз оно уже было повторено. Логика интервала времени повтора должна полагаться на переменную JMSXDeliveryCount.

message.getIntProperty("JMSXDeliveryCount ")

http://activemq.apache.org/activemq-message-properties.html

Это не способ сделать RedeliveryPolicy постоянным - он контролируется фабрикой соединений, и фабрика будет сброшена при перезагрузке сервера. То, как вы его настроили, будет продолжаться с тем поведением, которое вы видите, поскольку для useExponentialBackOff установлено значение true. Вы можете установить значение false, чтобы задержка была регулярной, но это единственное изменение.

Я думаю, что у вас есть правильная идея с установкой сообщения TTL, по крайней мере, это удалит сообщение через указанное время. JMSXDeliveryCount отличный, но он удалится после нескольких попыток, а не через определенный промежуток времени, если вы увеличите задержку между повторными попытками.

Другие вопросы по тегам