死信队列

Dead Letter Exchange 简称 DLX,可称为死信交换器,当消息在一个 队列中变成死信(dead message)之后,它能被重新发送到另一个交换器中,这个交换器就是 DLX,绑定在 DLX 上的队列就称为 死信队列
消息变成死信一般有以下几种情况:

  • 消息被拒绝,并设置 requeue 参数未 falseBasic.Reject 或 Basic.Nack
  • 消息过期
  • 队列达到最大长度

DLX 是一个普通的交换器,可以在任何队列上设置,当死信消息出现时,RabbitMQ 自动将这个 消息重新发布到设置的 DLX 上,从而被路由到另一个队列,即 死信队列
在队列定义时,使用 x-dead-letter-exchange 参数来为这个队列添加 DLX

  1. final Channel channel = connection.createChannel();
  2. // 定义 dlx
  3. channel.exchangeDeclare("exchange.dlx", "direct", true, false, null);
  4. // 定义 dlx queue
  5. channel.queueDeclare("queue.dlx", true, false, false, null);
  6. channel.queueBind("queue.dlx", "exchange.dlx", "dlx-routing-key");
  7. // 定义正常的交换器
  8. channel.exchangeDeclare("exchange.normal", "fanout", true, false, null);
  9. final HashMap<String, Object> arguments = new HashMap<>();
  10. // 定义队列事,通过该属性给该队列设置 DLX
  11. arguments.put("x-dead-letter-exchange", "exchange.dlx");
  12. // 还可以通过该属性重新消息的路由键,否则使用原消息的路由键
  13. arguments.put("x-dead-letter-routing-key", "dlx-routing-key");
  14. // 设置该队列的 ttl
  15. arguments.put("x-message-ttl", 10000);
  16. channel.queueDeclare("queue.normal", true, false, false, arguments);
  17. channel.queueBind("queue.normal", "exchange.normal", "");
  18. Copied!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

代码分为两部分:

  1. 定义一个 DLX(其实就是普通的交换器),但是会把他绑定在正常的交换器上;为该 DLX 绑定一个队列,用来接收死信消息
  2. 定义正常的交换器,并设置 DLX 交换器与路由键

在 web 管理界面中如下图所示:
image.png

  • D:durable 持久化队列
  • TTL:消息有过期时间
  • DLX:绑定了死信交换器
  • DLK:是这个 x-dead-letter-routing-key 死信交换器设置了路由键

一条消息过期时,就如下图所示,被转发到 DLX 交换器中
image.png
对于 RabbitMQ 来说, DLX 是非常有用的一个特性。还可以配合 TTL 实现延迟队列的功能。下一节讲解