0

We're using ActiveMQ 5.14.2.1 triggered by the Java Windows service wrapper, accessing from a Tomcat webapp using JMS and the Spring framework JMS (v4.3.28).

I'm trying to configure a redelivery policy so that when we return the message to the queue using session.rollback() it follows the policy. To do this, I set up the redeliveryPlugin in the activemq.xml file as follows:

<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>

I also updated the broker element to turn on schedulerSupport:

<amq:broker brokerName="MyBroker" dataDirectory="${activemq.data}" 
            useJmx="false" schedulerSupport="true">

I've tried a few permutations of this based on various documentation pages and several SO results, without success. Whatever I try it's using the default redelivery behavior (1 second between, no exponential backoff, max of 6 retries). I know it's reading this activemq.xml file, because when I put content that doesn't match the XSD it errors out.

What do I have to do to alter ActiveMQ's redelivery policy?

fool4jesus
  • 2,147
  • 3
  • 23
  • 34

1 Answers1

1

After lots of investigation and poking around in ActiveMQ with the debugger, I figured out what's going on. It turns out the configuration above is basically correct. I modified it slightly to:

<amq:redeliveryPolicy maximumRedeliveries="20" useExponentialBackOff="true" 
     initialRedeliveryDelay="5000" backOffMultiplier="2" maximumRedeliveryDelay="600000"/>

What is confusing though is the client side AND the server are both trying to do retries, but it appears they use different algorithms:

  • The client side initially makes 6 re-attempts, 1 second apart.
  • If those all fail, it sends the message back to ActiveMQ
  • ActiveMQ performs the redelivery behavior, which means to use the initial redelivery delay (5 sec)
  • If the messages still fail, the client again does re-tries at 1 second intervals, but this time it only makes 5 attempts.
  • ActiveMQ again does redelivery behavior, doubling the delay to 10s.
  • Upon re-delivery, the client again retries, but this time only 4 times before sending the message back to ActiveMQ.

This cycle keeps going, with the client reducing the number of local retries by 1 each time, and ActiveMQ increasing the retry time using exponential backoff. Finally, ActiveMQ sends the message at 10 minute intervals (the maximum delay), with the client doing 0 local retries on failures. I guess the idea in the client is to try to let the code solve the problem locally a few times, but it figures over time this becomes decreasingly likely.

fool4jesus
  • 2,147
  • 3
  • 23
  • 34