RabbitMq(三)死信队列

什么是RabbitMq死信队列

当一条消息在队列中出现以下三种情况的时候,该消息就会变成一条死信。

  • 消息被拒绝(basic.reject / basic.nack),并且禁止重新进入队列;requeue = false
  • 消息TTL过期
  • 队列达到最大长度

死信交换机、死信队列其实跟普通的交换机、队列是一样的

之所以叫死信是针对其功能特征而言的。正常的业务队列发生预期之外的异常;防止消息丢失,会将这种正常业务队列无法处理的消息,发送到死信交换机,再通过私信交换机绑定的路由键发送到对应的死信队列。

当消息在一个队列中变成一个死信之后,如果配置了死信队列,它将被重新publish到死信交换机,死信交换机将死信投递到一个队列上,这个队列就是死信队列。

死信队列模式图解

在这里插入图片描述

springboot配置代码

重点在于业务队列绑定死信交换机和死信路由键

/**
 * RabbitMQ配置类
 */
@Configuration
public class RabbitMqConfig {
    /**
     * 声明普通队列,并绑定死信队列
     */
    @Bean
    public Queue normalQueue() {
   	    Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange  这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", "deadeLetterQueue");
        // x-dead-letter-routing-key  这里声明当前队列的死信路由key
        // 如果此处没有配置路由KEY,将引用业务路由KEY到死信交换机中
        args.put("x-dead-letter-routing-key", "deadeRoutingKey");
        return new Queue("normalQueue", true, false, false);
    }
    /**
     * 声明普通交换机
     */
    @Bean
    DirectExchange normalExchange() {
        return new DirectExchange ("normalExchange", true, false);
    }
 
    @Bean
    Binding bindingNormalExchange() {
        return BindingBuilder
        .bind(normalQueue())
        .to(normalExchange())
        .with("normalRoutingKey");
    }
     /**
     * 声明死信队列
     */
    @Bean
    public Queue deadeLetterQueue() {
        return new Queue("deadeLetterQueue", true, false, false);
    }
    /**
     * 声明普通交换机
     */
    @Bean
    DirectExchange deadeLetterExchange() {
        return new DirectExchange ("deadeLetterExchange", true, false);
    }
    @Bean
    Binding bindingDeadeLetterExchange() {
        return BindingBuilder
        .bind(deadeLetterQueue())
        .to(deadeLetterExchange())
        .with("deadeRoutingKey");
    }
 
}

死信队列中的消息特性

在死信队列中的消息,会携带一些特殊信息;通过打印消息属性;可以看到,死信的消息中带了一些特殊属性;

system.out.println(message.getMessagePropertes())

x-first-death-exchange 第一次被抛入的死信交换机的名称
x-first-death-reason 第一次成为死信的原因,rejected:消息在重新进入队列时被队列拒绝,由于default-requeue-rejected 参数被设置为false。expired :消息过期。maxlen : 队列内消息数量超过队列最大容量
x-first-death-queue 第一次成为死信前所在队列名称
x-death 历次被投入死信交换机的信息列表,同一个消息每次进入一个死信交换机,这个数组的信息就会被更新

属性名说明
x-first-death-exchange第一次被抛入的死信交换机的名称
x-first-death-reason第一次成为死信的原因
default-requeue-rejected消费者配置了拒绝消息,不重新放回队列
x-first-death-queue第一次成为死信前所在队列名称
x-death历次被投入死信交换机的信息列表,同一个消息每次进入一个死信交换机,这个数组的信息就会被更新

死信队列实际开发中应用场景

对于比较重要的业务数据,在消费者发生了意料之外的异常,无法通过重新消费解决的;通过死信队列对数据进行存储,防止业务数据丢失;当开发排查出异常原因之后,人为的处理这些未被成功消费的业务数据。实际开发中也是通过人为的来处理这些数据的。


版权声明:本文为zps925458125原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。