javarabbitmqspring-rabbitdead-letterrabbitmq-shovel

How to reject messages after shoveling from one queue to another?


With Spring and RabbitMQ I set up two topic-exchanges xand dlx and two queues qand dlq. q is bound to x and dlq to dlx. dlx is configured as dead-letter-exchange for q.

When a message in q is rejected (with unqueue) it is successfully send to dlx and then to dlq.

Now I use the shovel-plugin to move dead-lettered messages in dlq back to q. This works successfully as long as the messages are processed successfully this time (ack).

But if one of these shovelled messages inq is rejected again it is dropped silently. I expect it to be send to the DLX dlx again. Did I configure something wrong or did I misunderstood the concept of DLX or shovels?


Solution

  • I suspect you are hitting a flavor of this...

    It is possible to form a cycle of message dead-lettering. For instance, this can happen when a queue dead-letters messages to the default exchange without specifiying a dead-letter routing key. Messages in such cycles (i.e. messages that reach the same queue twice) will be dropped if there was no rejections in the entire cycle.

    ...because you're shoveling. See Dead Letter Exchanges.

    Instead, configure the DLQ with TTL, and dead-letter configuration that causes expired messages to be routed back to the original queue. That way, the x-death header gets two entries - 1 for the rejections from the original queue and 1 for the expiry from the DLQ.

    I am guessing that, with shoveling, the broker thinks there is a cycle.