09.RabbitMQ死信队列

本文介绍了如何通过配置RabbitMQ的死信队列来避免消息丢失。当消息尝试多次消费失败、被拒绝或超过过期时间时,会进入死信队列。配置包括创建死信交换机、队列并绑定,以及在业务队列中设置死信交换机和路由键。通过示例代码展示了生产者发送消息和消费者模拟错误处理,演示了死信队列如何工作。
摘要由CSDN通过智能技术生成

在上篇中主要讲到了RabbitMQ手动响应消息,这篇主要讲到死信队列配置。

前面讲到RabbitMQ重试多次配置让他放弃消费,这样会导致消息丢失,除了放弃消费,消息丢失的情况还会有以下这几种:

  1. 尝试多次拒绝消费
  2. 消息设置了过期时间
  3. 消息队列满了

保证消息不丢失就需要用死信队列了,简单的讲就是指将消息放到另外一个队列,另外有一个消费者消费。

死信交换机配置类

@Configuration
class DeadExchangeConfig{

    /**
     * 创建死信队列
     */
    @Bean
    public Queue deadQueue(){
        return new Queue("DEAD_QUEUE");
    }

    /**
     * 创建死信交换机
     */
    @Bean
    public Exchange deadExchange(){
        return new DirectExchange("DEAD_EXCHANGE");
    }

    /**
     * 绑定死信交换机
     */
    @Bean
    public Binding bindingDeadExchange(Queue deadQueue, Exchange deadExchange) {
        return BindingBuilder.bind(deadQueue).to(deadExchange).with("DEAD_ROUTING").noargs();
    }

    /**
     * 创建用户业务队列
     */
    @Bean
    public Queue deadUserQueue(){
        Map<String, Object> map = new HashMap<>();
        // 绑定死信交换机
        map.put("x-dead-letter-exchange", "DEAD_EXCHANGE");
        // 绑定路由key
        map.put("x-dead-letter-routing-key", "DEAD_ROUTING");
        return new Queue("DEAD_USER_QUEUE", true, false, false, map);
    }

    /**
     * 创建用户业务交换机
     */
    @Bean
    public Exchange deadUserExchange(){
        return new DirectExchange("DEAD_USER_EXCHANGE");
    }

    /**
     * 用户业务交换机
     */
    @Bean
    public Binding bindingDeadUserExchange(Queue deadUserQueue, Exchange deadUserExchange) {
        return BindingBuilder.bind(deadUserQueue).to(deadUserExchange).with("DEAD_USER_ROUTING").noargs();
    }
}

队列管理页面可以看到,业务队列绑定了DLX和DLK,就说明已经绑定死信队列

image-20211119180906749

下面模拟让他报错,只重试一次,放弃消费

生产者

@RestController
@RequestMapping("/dead")
public class DeadUserCtrl {

    @Autowired
    private AmqpTemplate amqpTemplate;

    @GetMapping("/addUser")
    public String addUser(String msg){
        amqpTemplate.convertAndSend("DEAD_USER_EXCHANGE", "DEAD_USER_ROUTING", "terry");
        return msg;
    }
}

消费者

@Component
@RabbitListener(queues = "DEAD_USER_QUEUE")
class DeadUserQueueConsumer{

    @RabbitHandler
    public void receive(String msg){
        System.out.println(msg);
        throw new RuntimeException();
    }
}

配置类

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        retry:
          # 开启消费者重试机制(默认就是true,false则取消重试机制)
          enabled: true
          # 最大重试次数
          max-attempts: 1

运行,控制台报错,此时业务队列放弃消费的数据 已经放入到了死刑队列,如下图:

image-20211119182300531

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

terrybg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值