Backend Development 7 min read

Master RabbitMQ Dead-Letter Queues: When and How Messages Get Redirected

This guide explains RabbitMQ dead-letter queues, detailing the conditions that cause messages to become dead letters, how to configure exchanges and queues with x-dead-letter parameters, and demonstrates three testing methods—reject/nack, TTL expiration, and max-length overflow—using Spring Boot code examples.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master RabbitMQ Dead-Letter Queues: When and How Messages Get Redirected

Environment

Spring Boot 2.3.10 + RabbitMQ 3.8.12 + Erlang 23.2.5

Dead Letter Queue Introduction

Messages in a queue can become "dead letters" and be republished to an exchange when any of the following events occur:

The consumer calls basic.reject or basic.nack with the requeue parameter set to false .

The message has a TTL (set via x-message-ttl on the queue) and expires, or the queue exceeds its length limit and discards messages.

Note: Queue expiration (set via

x-expires

) does not cause its messages to become dead letters.

A dead‑letter exchange is a normal exchange and can be of any type.

When creating a queue, you can specify

x-dead-letter-exchange

and optionally

x-dead-letter-routing-key

to redirect messages that meet the above conditions.

Prepare Environment

Create the normal business exchange and queue needed for the workflow.

Create a

business-exchange

of type

topic

:

Create a dead‑letter exchange named

dead-exchange

of type

fanout

:

Create the business queue

business-queue

and bind it to the exchange, setting

x-dead-letter-exchange

to the dead‑letter exchange (no routing key needed because the dead‑letter exchange is

fanout

).

Test

Method 1: Consumer rejects with basic.reject or basic.nack

Send message endpoint:

<code>@GetMapping("/sendDeadLetter")
public Object sendDeadLetter(String msg) {
    ms.sendDeadLetter(msg);
    return "success";
}

public void sendDeadLetter(String msg) {
    logger.info("准备发送消息:{}", msg);
    rabbitTemplate.convertAndSend("business-exchange", "be.1", msg);
}
</code>

Message listener:

<code>@Component
public class MessageListener {

    @RabbitListener(queues = { "bussiness-queue" })
    @RabbitHandler
    public void listener1(Message message, Channel channel) {
        System.out.println("接受到消息.....income");
        byte[] body = message.getBody();
        MessageProperties mps = message.getMessageProperties();
        String content = new String(body, Charset.forName("UTF-8"));
        try {
            // Simulate rejection
            if ("1".equals(content)) {
                System.out.println("拒绝消息:1");
                channel.basicReject(mps.getDeliveryTag(), false);
                return;
            }
            System.out.println("接受到消息来自交换机: 【" + mps.getReceivedExchange() + "】, 队列:【" + mps.getConsumerQueue() + "】:\n\t\t内容: " + content);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                channel.basicReject(mps.getDeliveryTag(), false);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}
</code>

The listener rejects the message when the payload is "1".

Send a normal message:

Send a rejected message (payload "1"):

View the queues – the rejected message appears in the dead‑letter queue.

Method 2: Set message TTL (expiration)

Recreate

business-queue

with

x-message-ttl

set to 10000 ms (10 seconds).

Bind the queue to the exchange.

Send a message and wait 10 seconds; the expired message is automatically routed to the dead‑letter queue.

Method 3: Set maximum queue length

Delete the existing

bussiness-queue

and recreate it with

x-max-length=3

. Any message beyond the third is sent to the dead‑letter queue.

Send three messages – they stay in the queue. Sending a fourth message causes the oldest message to be moved to the dead‑letter queue.

The overflow message appears in the dead‑letter queue.

These examples demonstrate the situations in which RabbitMQ redirects messages to a dead‑letter queue.

End of tutorial.

Backend DevelopmentSpring BootRabbitMQMessage QueuingDead Letter Queue
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.