Search code examples
rabbitmqbunny

RabbitMQ - Scheduled Queue - Dead Letter Queue - Good practise


we have setup some workflow environment with Rabbit.

It solves our needs but I like to know if it is also good practise to do it like we do for scheduled tasks.

Scheduling means no mission critical 100% adjusted time. So if a job should be retried after 60 seconds, it does mean 60+ seconds, depends on when the queue is handled.

I have created one Q_WAIT and made some headers to transport settings.

Lets do it like:

Worker is running subscribed on Q_ACTION

If the action missed (e.g. smtp server not reachable)

-> (Re-)Publish the message to Q_WAIT and set properties.headers["scheduled"] = time + 60seconds


Another process loops every 15 seconds through all messages in Q_WAIT by method pop() and NOT by subscribed

q_WAIT.pop(:ack => true) do |delivery_info,properties,body|...

  if (properties.headers["scheduled"] has reached its time)

     -> (Re-)Publish the message back to Q_ACTION
        ack(message)

after each loop, the connection is closed so that the NOT (Re-)Published are left in Q_WAIT because they were not acknowledged.


Can someone confirm this as a working (good) practise.


Solution

  • Sure you can use looping process like described in original question.

    Also, you can utilize Time-To-Live Extension with Dead Letter Exchanges extension.

    First, specify x-dead-letter-exchange Q_WAIT queue argument equal to current exchange and x-dead-letter-routing-key equal to routing key that Q_ACTION bound.

    Then set x-message-ttl queue argument set or set message expires property during publishing if you need custom per-message ttl (which is not best practice though while there are some well-known caveats, but it works too).

    In this case your messages will be dead-lettered from Q_WAIT to Q_ACTION right after their ttl expires without any additional consumers, which is more reliable and stable.

    Note, if you need advanced re-publish logic (change message body, properties) you need additional queue (say Q_PRE_ACTION) to consume messages from, change them and then publish to target queue (say Q_ACTION).