什么是死信队列
死信队列:顾名思义,存放“死”了的消息的队列。当然了,并不是那个真正的死的意思,那么什么样的消息才被认为是“死”了的消息呢,有以下几种情况:
- 消息过期。超过了设置的过期时间(ttl)
- 队列超载。超出队列长度
- 被消费者拒绝回复(basic.reject/basic.nack),并且拒绝再次投递(requeue = false)
上图描述的就是一个消息被拒绝消费后如何进入死信队列的。消息过期主要用于实现延时队列,会在下面介绍。
使用场景
延时队列广泛的用于各种业务场景,比如常见的在12306购票时,订单在一定时间内自动关单。我们都知道MQ是即时消费的,那么能不能实现延时消费功能呢?
答案是肯定的。Rabbit MQ提供了一种死信队列配置,可以将消息保存在一个队列中一定时间(过期时间),然后会转发到一个死信交换机,再发送到绑定到此死信交换机上的队列上,然后被消费者消费,实现延时消费的功能。
如何配置死信队列
那么如何配置一个符合延时功能的死信队列呢?在这我们通过在Rabbit MQ的管理页面中配置,以便直观的观察并理解它。
配置之前,先通过一个简单的结构图辅助理解??
为了简便,下面创建的交换机均为直连类型(Direct)的交换机
1. 创建接收消费者消息的交换机
创建一个直连类型(Direct)的交换机create_exchange
注:其它配置参数项为
- Type:交换机类型
- Durability:持久化
- Auto delete:如果选择yes,此交换机将在至少有一个队列或交换机绑定到此交换机后,此交换机将自动删除,然后解除所有绑定关系
- Internal:如果选择yes,客户端将不能直接发送消息到此交换机,只能通过与其它交换机绑定来使用
2. 创建保存延时消息的队列
创建一个队列dead-queue。生产者提供的消息将被经由第一步创建的交换机保存到此队列,此队列需要配置消息的过期时间(x-message-ttl)、死信队列交换机(x-dead-letter-exchange)、死信队列和死信交换机的绑定规则(x-dead-letter-routing-key)。此队列中的消息过期后,按照队列的顺序转发给死信交换机。
注:其它配置参数项为
- Durability:持久化
- Auto delete:如果选择yes,此队列将在至少一个消费者连接后删除自已,然后断开所有消费者
3. 建立延时队列的绑定关系
将第二步创建的延时队列绑定到第一步创建的交换机上(Binding Key = create.event)
4. 创建死信交换机
创建一个用于接收延时队列中过期消息的交换机(dead_exchange)
5. 创建保存过期消息的队列
创建一个队列expire_queue。第四步收到的过期消息将发送到此队列,并被消费者消费。
6. 建立过期队列的绑定关系
将第五步创建的接收过期消息的队列绑定到第四步创建的死信交换机上(Binding Key = expire.event)
7. 测试死信队列
发送消息给create_exchange,指定Routing Key = create.event
查看队列dead_queue是否收到消息
进入队列查看详细信息
30s后,查看队列expire_queue是否收到消息,并观察dead_queue中的消息是否已出队
进入队列查看详细信息