Backend Development 7 min read

Master RabbitMQ Dead Letter Queues: When and How Messages Are Redirected

This guide explains RabbitMQ dead‑letter queues, covering the conditions that turn messages into dead letters, how to configure exchanges and queues with x‑dead‑letter‑exchange, TTL, and max‑length, and provides step‑by‑step Spring Boot code examples for testing each scenario.

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

Environment: Spring Boot 2.3.10, RabbitMQ 3.8.12, Erlang 23.2.5

Dead Letter Queue Introduction

Messages become dead letters when any of the following occurs:

Consumer calls

basic.reject

or

basic.nack

with

requeue=false

.

Message TTL expires (queue created with

x-message-ttl

) or the queue exceeds its length limit.

Note: Queue expiration set by

x-expires

does not generate dead letters.

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

When creating a queue, specify

x-dead-letter-exchange

and optionally

x-dead-letter-routing-key

to redirect dead letters to the designated exchange.

Setup Environment

Create the normal business exchange and queue.

Declare a

topic

exchange named

business-exchange

.

Declare a

fanout

exchange named

dead-exchange

(the dead‑letter exchange).

Create

business-queue

and bind it to

business-exchange

, setting

x-dead-letter-exchange

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

fanout

).

Test

Method 1: Consumer rejects a message using

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 reject scenario
            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>

When the message content is "1", the listener rejects it, and the message is routed to the dead‑letter queue.

Sending normal messages shows they are delivered to the original queue, while rejected messages appear in the dead‑letter queue.

Method 2: Message TTL Expiration

Recreate

business-queue

with

x-message-ttl=10000

(10 seconds) and bind it to the exchange.

After 10 seconds the expired messages are automatically transferred to the dead‑letter queue.

Method 3: Queue Length Limit

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.

Publish three messages; they stay in the queue. Publishing a fourth message causes the excess to be redirected to the dead‑letter queue.

These three methods demonstrate how RabbitMQ dead‑letter queues work and the situations that cause messages to be forwarded.

BackendSpring BootMessage QueueRabbitMQDead 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.