0
votes

If ActiveMQ Artemis is configured with a redelivery-delay > 0 and a JMS listener uses ctx.rollback() or ctx.recover() then the broker will redeliver the message as expected. But if a producer pushes a message to the queue during a redelivery then the receiver gets unordered messages.

For example:

Queue: 1 -> message 1 is redelivered as expected

Push during the redelivery phase

Queue: 2,3 -> the receiver gets 2,3,1

With a redelivery-delay of 0 everything is ok, but the frequency of redeliveries on consumer side is too high. My expectation is that every delivery to the consumer should be stopped until the unacknowledged message is purged from the queue or acknowledged. We are using a queue for connection with single devices. Every device has it's own I/O queue with a single consumer. The word queue suggest strict ordering to me. It could be nice to make this behavior configurable like "strict_redelivery_order".

1
Create a broker config with a redelivery deleay of 1ms. Push a message and then roll it back. After this artemis redilvers the message as expeted. Every 1ms. And push now a second messge. This will deliverd imediatly. My expectation is that every delivery to the consumer should be stoppend until the not acknowledged messege is prurged or acked from the queueSüleyman Vurucu
I agree for general purpose usage. But we are using queue for connection with single devices. Every device has it's own I/O queue with single responsible consumer. The word queue suggest me strict ordering. It could be nice to make this behviuour configurable like "strict_redelivery_order"Süleyman Vurucu

1 Answers

0
votes

What you're seeing is the expected behavior. If you use a redelivery-delay > 0 then delivery order will be broken. If you use a redelivery-delay of 0 then delivery order will not be broken. Therefore, if you want to maintain strict order then use a redelivery-delay of 0.

If the broker blocked delivery of all other messages on the queue during a redelivery delay that would completely destroy message throughput performance. What if the redelivery delay were 60 seconds or 10 minutes? The queue would be blocked that entire time. This would not be tenable for an enterprise message broker serving hundreds or perhaps thousands of clients each of whom may regularly be triggering redeliveries on shared queues. This behavior is not configurable.

If you absolutely must maintain message order even for messages that cannot be immediately consumed and a redelivery-delay of 0 causes redeliveries that are too fast then I see a few potential options (in no particular order):

  • Configure a dead-letter address and set a max-delivery-attempts to a suitable value so after a few redeliveries the problematic message can be cleared from the queue.
  • Implement a delay of your own in your client. This could be as simple as catching any exception and using a Thread.sleep() before calling ctx.rollback().