• RabbitMQ-死信交换机和死信队列


    1. 简介

    1.1 DLX简介

    DLX: Dead-Letter-Exchange 死信交换器,死信邮箱

    当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。
    如下图所示:
    在这里插入图片描述
    其实死信队列就是一个普通的交换机,有些队列的消息成为死信后,(比如过期了或者队列满了)这些死信一般情况下是会被 RabbitMQ 清理的。但是你可以配置某个交换机为此队列的死信交换机,该队列的消息成为死信后会被重新发送到此 DLX 。怎么处理这个DLX中的死信就是看具体的业务场景了,DLX 中的信息可以被路由到新的队列。

    2.2 出现死信的情况

    • 队列长度到达限制,无法加入新的消息
    • 消费者拒接消费消息,并且不重回队列。该信息会被清除并进入死信队列
    • 原队列存在消息过期设置,消息到达超时时间未被消费

    2.3 代码示例

    死信队列可以定义单条消息和整个队列死信,分别是下方的2和4。

    2.代码示例

    以下定义了两个交换机,分别是普通交换机和死信交换机,定义了两个队列,分别是普通队列和死信队列。

    @Configuration
    public class RabbitConfig {
        final static String exchangeNormalName = "exchange.dlx.normal";
        final static String queueNormalName = "queue.dlx.normal";
        final static String exchangeDeadName = "exchange.dlx.dead";
        final static String queueDeadName = "queue.dlx.dead";
    
    
        //正常交换机
        @Bean
        public DirectExchange normalExchange(){
            return ExchangeBuilder.directExchange(exchangeNormalName).build();
        }
        //正常队列
        @Bean
        public Queue normalQueue(){
            Map<String, Object> map = new HashMap<>();
            map.put("x-message-ttl", 20000);//设置20s的过期时间
            map.put("x-dead-letter-exchange", exchangeDeadName);//设置死信交换机名字
            map.put("x-dead-letter-routing-key", "error");//设置死信交换机路由k
            return QueueBuilder.durable(queueNormalName)
                    .withArguments(map)
                    .build();
        }
    
        @Bean
        public Binding normalBinding(DirectExchange normalExchange, Queue normalQueue){
            return BindingBuilder.bind(normalQueue).to(normalExchange).with("order");
        }
    
    
        //死信交换机
        @Bean
        public DirectExchange dlxExchange(){
            return ExchangeBuilder.directExchange(exchangeDeadName).build();
        }
        //死信队列
        @Bean
        public Queue dlxQueue(){
            return QueueBuilder.durable(queueDeadName).build();
        }
    
        @Bean
        public Binding dlxBinding(DirectExchange dlxExchange, Queue dlxQueue){
            return BindingBuilder.bind(dlxQueue).to(dlxExchange).with("error");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    如上,设置普通交换机把过期内容放置到死信交换机中去。最重要的几行代码如下:

    • map.put(“x-message-ttl”, 20000);//设置20s的过期时间
    • map.put(“x-dead-letter-exchange”, exchangeDeadName);//设置死信交换机名字
    • map.put(“x-dead-letter-routing-key”, “error”);//设置死信交换机路由key

    3.测试结果

    在这里插入图片描述

    经过20s之后,如下,将普通队列的信息放入死信队列中

    在这里插入图片描述
    其中TTL代表x-message-ttl,DLX代表x-dead-letter-exchange,DLK代表x-dead-letter-routing-key

    4.单条消息

    上方是将整个队列设置过期时间,也可以将单条消息设置过期时间,即不给整个队列设置过期时间

    		//map.put("x-message-ttl", 20000);//设置20s的过期时间
            map.put("x-dead-letter-exchange", exchangeDeadName);//设置死信交换机名字
            map.put("x-dead-letter-routing-key", "error");//设置死信交换机路由k
    
    • 1
    • 2
    • 3

    而是在消息体中设置过期时间

    @Component
    @Slf4j
    public class MessageService {
        @Autowired
        private RabbitTemplate rabbitTemplate;
        public void senMsg() throws InterruptedException {
    
            //定义消息
            String msg="单条消息过期时间test";
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setExpiration("10000"); //10s
            Message message= MessageBuilder.withBody(msg.getBytes()).andProperties(messageProperties).build();
            //发消息
            rabbitTemplate.convertAndSend("exchange.dlx.normal","order",message);
            log.info("消息发送完毕,发送时间为:{}", new Date());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    Python实现人脸识别
    第5章-宏观业务分析方法-5.5-多维尺度分析
    高精度数字压力表丨铭控传感多款数字压力表在多场景中的应用
    offline RL | ABM:从 offline dataset 的好 transition 提取 prior policy
    使用ElementUI结合Vue完善主页的导航菜单和书籍管理的后台数据分页查询
    vue ---列表渲染
    家居建材小程序商城开发
    中国针织行业市场深度分析及发展规划咨询综合研究报告
    Kubernetes概述及其组件/核心组件
    Redis 字符串( String )
  • 原文地址:https://blog.csdn.net/qq_43471945/article/details/134080539