RabbitMQ死信队列

死信队列

面试题: 你们是如何保证消息不丢失的?

1、什么是死信

在 RabbitMQ 中充当主角的就是消息,在不同场景下,消息会有不同地表现。

死信就是消息在特定场景下的一种表现形式,这些场景包括:

  1. 消息被拒绝访问,即消费者返回 basicNack 的信号时 或者拒绝basicReject

2. 消费者发生异常,超过重试次数 。 ( 其实spring框架调用的就是 basicNack**)**

  1. 消息的Expiration 过期时长或队列TTL过期时间。.ttl(20*1000) 进入的是 先进业务队列的数据

  2. 消息队列达到最大容量 .maxLength(5)

上述场景经常产生死信,即消息在这些场景中时,被称为死信。

2、什么是死信队列

死信队列就是用于储存死信的消息队列,在死信队列中,有且只有死信构成,不会存在其余类型的消息。

死信队列在 RabbitMQ 中并不会单独存在,往往死信队列都会绑定这一个普通的业务消息队列,当所绑定的消息队列中,有消息变成死信了,那么这个消息就会重新被死信交换机路由到指定的死信队列中去,我们可以通过对这个死信队列进行监听,从而手动的去对这一消息进行补偿。 人工干预

3、那么,我们到底如何来使用死信队列呢?

死信队列基本使用,只需要在声明业务队列的时候,绑定指定的死信交换机和RoutingKey即可。

java 复制代码
 @Bean //死信交换机
    public DirectExchange deadExchange() {
        return   ExchangeBuilder.directExchange("dead_ex").durable(true).build();
    }
    @Bean //死信队列
    public Queue deadQueue() {
        return  QueueBuilder.durable("dead_ordering_ok_wms").build();
    }
    @Bean //绑定死信队列与死信交换机的关系
    public Binding bindingDead(){
        return   BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead_ordering_ok_wms");
    }
    @Bean  //业务交换机
    public FanoutExchange exchange() {
        return    ExchangeBuilder.fanoutExchange("ordering_ok").durable(true).build();
    }
    @Bean //业务队列
    public Queue queue() {
        return  QueueBuilder
                .durable("ordering_ok_wms")
                .deadLetterExchange("dead_ex")
                .deadLetterRoutingKey("dead_ordering_ok_wms")
                //.ttl(20*1000) //该属性是队列的属性,设置消息的过期时间,消息在队列里面停留时间n毫秒后,就会把这个消息投递到死信交换机,针对的是所有的消息
                //.maxLength(5) //设置队列存放消息的最大个数,x-max-length属性值,当队列里面消息超过20,会把队列之前的消息依次放进死信队列
                .build();
    }

    @Bean //业务绑定队列与交换机的关系
    public Binding binding(){
      return   BindingBuilder.bind(queue()).to(exchange());
    }


   // @RabbitListener(queues = "ordering_ok_wms")
    public  void  consume(OrderingOk msg) throws IOException {
            log.debug("wms处理订单->{}",msg);
            int i = 1/0;
    }

4. 自动应答死信配置

#-------------MQ 高级配置---------

#预抓取数量

spring.rabbitmq.listener.simple.prefetch=250

#设置消费者手动应答模式

spring.rabbitmq.listener.simple.acknowledge-mode = auto

#开启自动应答重试机制

spring.rabbitmq.listener.simple.retry.enabled=true

#默认重试3次

spring.rabbitmq.listener.simple.retry.max-attempts=3

#重试间隔时间 单位ms

spring.rabbitmq.listener.simple.retry.initial-interval=1000ms

#时间间隔倍数,默认是1倍

spring.rabbitmq.listener.simple.retry.multiplier=2

#最大间隔时间

spring.rabbitmq.listener.simple.retry.max-interval=5000ms

相关推荐
初次攀爬者1 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧2 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖2 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
予枫的编程笔记2 天前
【Kafka高级篇】避开Kafka原生重试坑,Java业务端自建DLQ体系,让消息不丢失、不积压
java·kafka·死信队列·消息中间件·消息重试·dlq·java业务开发
断手当码农2 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者2 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀2 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3052 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05092 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式
凉凉的知识库2 天前
Go中的零值与空值,你搞懂了么?
分布式·面试·go