The problem
Your consumer can not handle the received message and you need to reject it. If you reject the message with requeue being true, it will be instantly redelivered to your consumer, resulting in very high workload, as your consumer will reject that message. Things have come full circle π
Basicaly you want to reject the message and requeue it, but with a delay.
The solution
Well, you could not reject the message, but you could deliver it to another queue from your consumer and write a cronjob moving this messages back to the working queue. But there should be a better solution, and it should be possible to implement without any changes to your consumer or your message broker.
The real solution
Dead-Letter-Exchange (DLX) to the rescue!
For every queue you can specify a DLX, this is where messages that got rejected or deleted will be delivered to. In combination with a TTL you can automate delivery between queues with a delay.
To make this work, setup your exchanges and queues like so:
- create an exchange named
stuff
and direct bind to the queuestuff
- create an exchange named
stuff-retry
and direct bind to the queuestuff-retry
- create a work queue named
stuff
with thex-dead-letter-exchange
header set tostuff-retry
- create a work queue named
stuff-retry
with thex-dead-letter-exchange
header set tostuff
and thex-message-ttl
header to300000
Thatβs it. If your consumer listening on stuff
now rejects a message without requeue, it will be delivered to the stuff-retry-exchange
which passes the message on to the stuff-retry-queue
. After five minutes in that queue, the messages dies and will be redelivered to the stuff-exchange
, which passes the message on to the stuff-queue
so your consumer can process that message.
Top comments (0)