Reputation: 15755
I need to schedule delay messages, so I declare a delay queue DELAY_STAT with x-dead-letter-exchange and x-dead-letter-routing-key which will route to the default exchange to my destination queue STAT.
When I need to schedule a delay message to queue STAT, I publish the message to DELAY_STAT with expiration, and when the message ttl are reached, it will be a dead letter and then be routed to STAT so that it can be consumed.
But I encounter a problem, according to https://www.rabbitmq.com/ttl.html#per-message-ttl-caveats
When setting per-message TTL expired messages can queue up behind non-expired ones until the latter are consumed or expired
which means some short delay message A will be stucked by long delay message B if B is sent earlier.
Upvotes: 0
Views: 741
Reputation: 1546
If you want to schedule messages to deliver you may to do the following.
E.g.
Let's assume that your time window is 60 seconds, so you will have a separate queue for messages with TTL between 0 and 59 seconds (inclusive) with name e.g. queue.dlx.0
, a separate queue for messages with TTL between 60 and 119 seconds with name queue.dlx.0
and so on.
You know that for current message TTL equal to 50 seconds. Then, you may define delayed queue name queue.dlx
+ Math.floor(50 / 60)
When message TTL expires it dies and goes to queue where you have a consumer to process the messages.
Also, you may create a queue for each message and setup queue TTL (x-expires
) to delete the queue after expiring message TTL (message TTL + several seconds just in case)
See this picture: https://hsto.org/getpro/habr/post_images/1a2/95d/14f/1a295d14fbeea180e17636a86e8fbce6.png
(source - https://habr.com/post/235983/ [RUS])
Also, you may take a look at this plugin https://github.com/rabbitmq/rabbitmq-delayed-message-exchange.
Math.floor - JS function to round fractional number to lowest integer number.
Upvotes: 0