RabbitMQ深度探索:死信队列

  1. 死信队列产生背景:
    1. RabbitMQ 死信队列俗称 备胎队列:消息中间件因为某种原因拒收该消息后,可以转移到私信队列中存放,死信队列也可以有交换机和路由 key 等
  2. 生产死信队列的原因:
    1. 消息投递到 MQ 存放,消息已经过期,消费者没有及时获取到我们的消息,消息如果存放到 MQ 服务器中过期之后,会转移到备胎死信队列存放
    2. 多列达到最大长度(队列已满)
    3. 消费者消费多次消息失败,就会转义到私信队列中
  3. 案例:
    1. 配置类:
      @Component
      public class DeadExchangeConfig {
          //普通交换机
          @Value("${boyatop.order.exchange}")
          private  String order_exchange;
      
          //普通队列
          @Value("${boyatop.order.queue}")
          private String order_queue;
      
          //普通队列的 key
          @Value("${boyatop.order.routingKey}")
          private String order_rotingKey;
      
          //死信交换机
          @Value("${boyatop.dlx.exchange}")
          private String dlx_exchange;
      
          //死信队列
          @Value("${boyatop.dlx.queue}")
          private String dlx_queue;
      
          //死信队列的 key
          @Value("${boyatop.dlx.routingKey}")
          private String dlx_routingKey;
      
          //定义死信交换机
          @Bean
          public DirectExchange dlxExchange(){
              return new DirectExchange(dlx_exchange);
          }
      
          //定义死信队列
          @Bean
          public Queue dlxQueue(){
              return new Queue(dlx_queue);
          }
      
          //定义普通交换机
          @Bean
          public DirectExchange orderExchange(){
              return new DirectExchange(order_exchange);
          }
      
          //定义普通队列
          @Bean
          public Queue orderQueue(){
              //订单队列绑定死信交换机
              Map<String,Object> arguments = new HashMap<>(2);
              arguments.put("x-dead-letter-exchange",dlx_exchange);
              arguments.put("x-dead-letter-routing-key",dlx_routingKey);
              return new Queue(order_queue,true,false,false,arguments);
      //        return QueueBuilder.durable(order_queue).withArguments(arguments).build();
          }
      
      
          //订单队列绑定交换机
          @Bean
          public Binding bindingOrderExchange(DirectExchange orderExchange, Queue orderQueue){
              return BindingBuilder.bind(orderQueue)
                      .to(orderExchange)
                      .with(order_rotingKey);
          }
      
          //死信队列绑定交换机
          @Bean
          public Binding bindingDlxExchange(DirectExchange dlxExchange, Queue dlxQueue){
              return BindingBuilder.bind(dlxQueue).to(dlxExchange).with(dlx_routingKey);
          }
      
      }
    2. 生产者:
      @RestController
      public class producerService {
      
          @Value("${boyatop.order.exchange}")
          private String orderExchange;
      
          @Value("${boyatop.order.routingKey}")
          private String orderRouTingKey;
      
          @Autowired
          RabbitTemplate rabbitTemplate;
      
          @RequestMapping("/sendMsg")
          public String send(){
              String msg = "11111";
              rabbitTemplate.convertAndSend(orderExchange,orderRouTingKey,msg,message -> {
                  //设置超时时间
                  message.getMessageProperties().setExpiration("5000");
                  return message;
              });
              return "success";
          }
      
      }
    3. yml 文件:
      spring:
        rabbitmq:
          ####连接地址
          host: 127.0.0.1
          ####端口号
          port: 5672
          ####账号
          username: guest
          ####密码
          password: guest
          ### 地址
          virtual-host: boyatopVirtualHost
      
      #演示死信队列
      boyatop:
        #备胎交换机
        dlx:
          exchange: boyatop_dlx_exchange
          queue: boyatop_dlx_queue
          routingKey: dlx
        #普通交换机
        order:
          exchange: boyatop_order_exchange
          queue: boyatop_order_queue
          routingKey: order
  4. 死信队列架构原理:
    1. 死信队列和普通队列区别不是很大
    2. 普通队列和死信队列都有自己独立的交换机、路由 key、队列和消费者
    3. 区别:
      1. 生产者投递消息先投递到普通交换机中,普通交换机再将该消息投到普通队列中缓存起来,普通队列对应有自己独立的消费者
      2. 如果生产者投递消息到普通队列中,普通队列发现该消息一直没有被消费者消费的情况下,这时候会将该消息转移到死信(备胎)交换机中
      3. 死信(备胎)交换机对应有自己独立的死信(备胎)队列,对应独立的死信(备胎)消费者
  5. 死信队列应用场景:
    1. 30 分钟订单超时设计
      1. redis 过期 key
      2. 死信延迟队列实现
    2. 采用死信队列,创建一个普通队列没有对应的消费者消费该消息,在 30 分钟过后就会将该消息转移到死信备胎消费者实现消费
    3. 死信备胎消费者会根据订单号码查询是否已经支付过,如果没有支付的情况下则会开始回滚库存操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值