无法更改 ActiveMQ redeliveryPolicy
Can't change ActiveMQ redeliveryPolicy
我们正在使用由 Java Windows service wrapper 触发的 ActiveMQ 5.14.2.1,使用 JMS 和 Spring 框架 JMS (v4.3.28) 从 Tomcat webapp 访问。
我正在尝试配置重新传递策略,以便当我们return 使用session.rollback()
将消息发送到队列时它遵循该策略。为此,我在 activemq.xml
文件中设置 redeliveryPlugin
如下:
<amq:redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
<amq:redeliveryPolicyMap>
<amq:redeliveryPolicyMap>
<amq:defaultEntry>
<amq:redeliveryPolicy maximumRedeliveries="20" useExponentialBackOff="true"
initialRedeliveryDelay="1000" redeliveryDelay="2000" maximumRedeliveryDelay="600000"/>
</amq:defaultEntry>
</amq:redeliveryPolicyMap>
</amq:redeliveryPolicyMap>
</amq:redeliveryPlugin>
我还更新了 broker 元素以打开 schedulerSupport:
<amq:broker brokerName="MyBroker" dataDirectory="${activemq.data}"
useJmx="false" schedulerSupport="true">
我尝试了一些基于各种 documentation pages and several SO results 的排列,但没有成功。无论我尝试什么,它都使用默认的重新传递行为(间隔 1 秒,没有指数退避,最多 6 次重试)。我知道它正在读取这个 activemq.xml
文件,因为当我输入与 XSD 不匹配的内容时它会出错。
我需要做什么才能改变 ActiveMQ 的重新传递策略?
经过大量调查并使用调试器在 ActiveMQ 中摸索之后,我弄清楚了发生了什么。事实证明上面的配置基本上是正确的。我稍微修改为:
<amq:redeliveryPolicy maximumRedeliveries="20" useExponentialBackOff="true"
initialRedeliveryDelay="5000" backOffMultiplier="2" maximumRedeliveryDelay="600000"/>
令人困惑的是客户端和服务器都在尝试重试,但它们似乎使用了不同的算法:
- 客户端最初进行 6 次重试,间隔 1 秒。
- 如果这些都失败了,它将消息发送回 ActiveMQ
- ActiveMQ执行再投递行为,即使用初始再投递延迟(5秒)
- 如果消息仍然失败,客户端将再次以 1 秒的间隔重试,但这次它只进行 5 次尝试。
- ActiveMQ 再次执行重新传递行为,将延迟加倍至 10 秒。
- 重新传递后,客户端再次重试,但这次在将消息发送回 ActiveMQ 之前仅重试 4 次。
这样循环下去,客户端每次将本地重试次数减1,ActiveMQ使用指数退避算法增加重试时间。最后,ActiveMQ 以 10 分钟的间隔(最大延迟)发送消息,客户端在失败时进行 0 次本地重试。我猜客户端的想法是尝试让代码在本地解决几次问题,但随着时间的推移,这种可能性越来越小。
我们正在使用由 Java Windows service wrapper 触发的 ActiveMQ 5.14.2.1,使用 JMS 和 Spring 框架 JMS (v4.3.28) 从 Tomcat webapp 访问。
我正在尝试配置重新传递策略,以便当我们return 使用session.rollback()
将消息发送到队列时它遵循该策略。为此,我在 activemq.xml
文件中设置 redeliveryPlugin
如下:
<amq:redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
<amq:redeliveryPolicyMap>
<amq:redeliveryPolicyMap>
<amq:defaultEntry>
<amq:redeliveryPolicy maximumRedeliveries="20" useExponentialBackOff="true"
initialRedeliveryDelay="1000" redeliveryDelay="2000" maximumRedeliveryDelay="600000"/>
</amq:defaultEntry>
</amq:redeliveryPolicyMap>
</amq:redeliveryPolicyMap>
</amq:redeliveryPlugin>
我还更新了 broker 元素以打开 schedulerSupport:
<amq:broker brokerName="MyBroker" dataDirectory="${activemq.data}"
useJmx="false" schedulerSupport="true">
我尝试了一些基于各种 documentation pages and several SO results 的排列,但没有成功。无论我尝试什么,它都使用默认的重新传递行为(间隔 1 秒,没有指数退避,最多 6 次重试)。我知道它正在读取这个 activemq.xml
文件,因为当我输入与 XSD 不匹配的内容时它会出错。
我需要做什么才能改变 ActiveMQ 的重新传递策略?
经过大量调查并使用调试器在 ActiveMQ 中摸索之后,我弄清楚了发生了什么。事实证明上面的配置基本上是正确的。我稍微修改为:
<amq:redeliveryPolicy maximumRedeliveries="20" useExponentialBackOff="true"
initialRedeliveryDelay="5000" backOffMultiplier="2" maximumRedeliveryDelay="600000"/>
令人困惑的是客户端和服务器都在尝试重试,但它们似乎使用了不同的算法:
- 客户端最初进行 6 次重试,间隔 1 秒。
- 如果这些都失败了,它将消息发送回 ActiveMQ
- ActiveMQ执行再投递行为,即使用初始再投递延迟(5秒)
- 如果消息仍然失败,客户端将再次以 1 秒的间隔重试,但这次它只进行 5 次尝试。
- ActiveMQ 再次执行重新传递行为,将延迟加倍至 10 秒。
- 重新传递后,客户端再次重试,但这次在将消息发送回 ActiveMQ 之前仅重试 4 次。
这样循环下去,客户端每次将本地重试次数减1,ActiveMQ使用指数退避算法增加重试时间。最后,ActiveMQ 以 10 分钟的间隔(最大延迟)发送消息,客户端在失败时进行 0 次本地重试。我猜客户端的想法是尝试让代码在本地解决几次问题,但随着时间的推移,这种可能性越来越小。