2

To clarify the title: I am using ActiveMQ 5.15.15 (NOT the Artemis engine), and I am using AMQP 1.0 without official JMS libraries. And to be more specific, I am using the AmazonMQ version of this, which will soon upgrade to 5.16.2. I could force the upgrade, if needed.

I'm using an AMQP 1.0 compatible library (rhea) that has served us well so far, but I'm not finding any documentation for how to get ActiveMQ's redelivery plugin to work with my library. The library maintainers are unaware with how this is exposed via ActiveMQ, as well.

I've not been able to get the redelivery plugin to work, despite trying to add various headers, delivery annotations, message annotations, or application properties. I do have schedulerSupport="true" in my broker element for the server config.

These are the keys I've tried, and the values are numeric. E.g., 30000 for 30 seconds before allowing a consumer/subscriber see the message in the queue. I saw them in various docs, and it didn't hurt to try them.

  • AMQ_SCHEDULED_DELAY
  • x-opt-delivery-delay
  • _AMQ_SCHED_DELIVERY

I have also released the message from the client, meaning it failed to deliver (also passing a value that signals the failure to the broker and increases the attempted delivery count). While the number of delivery attempts increased, the delay and exponential backoff have not seemed to be working at the broker level.

I see that the STOMP protocol allows for headers when publishing, which allow setting options a bit more clearly. However, I don't want to switch everything over unless it makes sense to do so.

I also saw another ability to send a delayed message as a topic via the REST API, but I'm not sure if that was intended to be a production use case.

So right now, I'm either looking at:

  1. hold the message in memory for a bit and attempt to republish or release it after a delay
  2. Investigate STOMP, see if the redelivery plugin works with that

But I'm hoping someone knows where to implement this.

My redeliveryPolicy is basic:


               <!--
               The Redelivery plugin extends the capabilities of destination policies with respect to message redelivery.
               For more information, see http://activemq.apache.org/message-redelivery-and-dlq-handling.html
               -->
               <redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
                 <redeliveryPolicyMap>
                   <redeliveryPolicyMap>
                     <redeliveryPolicyEntries>
                       <!--<redeliveryPolicy maximumRedeliveries="4" queue="SpecialQueue" redeliveryDelay="10000"/>-->
                     </redeliveryPolicyEntries>
                     <defaultEntry>
                       <!-- 5s -> 15s -> 45s -> 135s -> 405s -->
                       <redeliveryPolicy backOffMultiplier="3" initialRedeliveryDelay="5000" maximumRedeliveries="5"/>
                     </defaultEntry>
                   </redeliveryPolicyMap>
                 </redeliveryPolicyMap>
               </redeliveryPlugin>

Update

I am using the auth plugin, and there's an entry that seems like it's for a built-in process. I think this came from a sample/default config. There doesn't appear to be a whole lot of documentation around this from a quick search. I can try opening access to other users, but each update/restart can take up to 15 minutes with the current setup.

<authorizationEntry admin="administrators" queue="SchedulingProcessor.>" write="scheduling-processor"/>

Comment Clarifications

  • My main objective is to delay redeliveries, so consumers don't see a failed message that was placed back into the queue for n seconds.
  • I started with no special headers/properties/annotations + the redelivery plugin, which also didn't work.
ps2goat
  • 8,067
  • 1
  • 35
  • 68
  • is that a typo in the `defaultEntry` comments (in this question) or is the typo in the config file as well? – blurfus Sep 09 '21 at 01:53
  • @blurfus - Yes, good catch. That was only me adding the time comment for this question. – ps2goat Sep 09 '21 at 09:51
  • The redelivery plugin doesn't care about headers in the messages for delayed delivery so the question is confusing. What is it you are after delayed delivery or redelivery delays? – Tim Bish Sep 09 '21 at 14:06
  • @TimBish redelivery delays, but I've also tried delaying initial delivery of a new message and neither have worked, yet. The main goal is how do I accomplish this without a JMS-specific implementation. – ps2goat Sep 09 '21 at 14:54
  • In terms of [official documentation](https://activemq.apache.org/delay-and-schedule-message-delivery), it appears there is no distinction between the two delay types. – ps2goat Sep 09 '21 at 15:10
  • Did you solve this issue yet? If yes please tell me how you did it. – Anurag Phadnis Oct 03 '22 at 08:36

1 Answers1

0

There is a distinction around message delivery delay and message redelivery delay that I think you are confusing or at least the question is mixing up.

A sender can request that a message be delivered after some delay from an AMQP client using the Message Annotations section of the sent message and adding in 'x-opt-delivery-delay' or 'x-opt-delivery-time' annotation assuming the broker has enabled scheduled deliveries. Some examples of this can be found in the ActiveMQ unit test. The delay annotation indicates a relative delay from time of receipt in milliseconds while the delivery time annotation indicates a time in UTC to deliver the message.

The ActiveMQ 5 redelivery policy affects messages that have been explicitly tagged as not deliverable on the client and therefore the AMQP Released outcome is not the right choice to trigger this behavior as it simply indicates that the client isn't going to process it and the remote should consider it undelivered and send it elsewhere. You would need to use one of Rejected or Modified(undeliverableHere=true) to "poison" the message and trigger the redelivery policy. This should if things go right trigger a redelivery after some delay although since ActiveMQ 5 has a relatively basic AMQP protocol head it will likely resend to the same consumer even if you've explicitly set the undeliverable here flag. I don't know how much that bit has been tested if any so your mileage may vary.

Tim Bish
  • 17,475
  • 4
  • 32
  • 42
  • I did use `x-opt-delivery-delay` with a new message but still received it immediately in my client app. I'm not delivering at a specific time, only specifying the delay in milliseconds. Your linked source is JMS based; my question in summary was how to get ActiveMQ to recognize a delay without using a JMS client library. I'm using an AMQP 1.0 library, but looking to add the capabilities of ActiveMQ into it. I will try again with the `rejected` method, as the same consumer should be able to retry (just delaying in case an external service is unavailable). – ps2goat Sep 09 '21 at 19:30
  • This link test is definitely not JMS based (it is java based if you are confused) but uses a custom AMQP test client for the broker. You should ensure you used Message Annotations for the delay value and not Application Properties – Tim Bish Sep 09 '21 at 20:01