Постоянный 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'] < 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 ")
Это не способ сделать RedeliveryPolicy постоянным - он контролируется фабрикой соединений, и фабрика будет сброшена при перезагрузке сервера. То, как вы его настроили, будет продолжаться с тем поведением, которое вы видите, поскольку для useExponentialBackOff установлено значение true. Вы можете установить значение false, чтобы задержка была регулярной, но это единственное изменение.
Я думаю, что у вас есть правильная идея с установкой сообщения TTL, по крайней мере, это удалит сообщение через указанное время. JMSXDeliveryCount отличный, но он удалится после нескольких попыток, а не через определенный промежуток времени, если вы увеличите задержку между повторными попытками.