zoukankan      html  css  js  c++  java
  • springboot整合rabbirmq(3.7.9)中使用mandatory参数获取匹配失败的消息以及存入rabbitmq备份交换器中!

    先说下这个参数的作用:

    /**
    * Mandatory为true时,消息通过交换器无法匹配到队列会返回给生产者
    * 为false时,匹配不到会直接被丢弃
    */
    在一些特定场景下还是有用处的!
    接下来说一下绑定队列与交换器,需要在配置类或者xml中提前配置好
    尤其是queue,如果同时写了消费者,必须先配置好bean,即mq中队列必须存在,不然会报错
        //创建消息队列
        @Bean
        public Queue testQueue(){
            //boolean表示消息是否持久化
            return new Queue("testQueue",true);
        }
        //创建交换器
        @Bean
        public DirectExchange exchange(){
            //boolean表示消息是否持久化
            return new DirectExchange("exchange");
        }
        //通过指定key绑定队列与交换器
        @Bean
        Binding bindingExchangeMessages(@Qualifier("testQueue") Queue queue, DirectExchange exchange) {
            return BindingBuilder.bind(queue).to(exchange).with("routeKey");
        }
    

      绑定好之后就可以测试这个参数了,使用我们指定的交换器和key!

    程序启动之后会自动创建,这里如果需要捕获匹配失败的消息需要添加一个监听器

    测试:当参数设置为true时,写个错误的key:

        @Override
        public void sendTest() {
            /**
             * Mandatory为true时,消息通过交换器无法匹配到队列会返回给生产者
             *          为false时,匹配不到会直接被丢弃
             */
            rabbitTemplate.setMandatory(true);
            //添加监听器获取返送失败的消息
            rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
                @Override
                public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                    System.out.println("replyCode:"+replyCode);
                    System.out.println("replyText:"+replyText);
                    System.out.println("匹配队列失败,返回消息:" + message.toString());
                }
            });
            // 向指定交换器发送消息,需要key
            rabbitTemplate.convertAndSend("exchange","route","测试消息内容");
        }
    

     由于key不对,匹配队列失败,参数为true,所以消息会返回给生产者:

    如果写上正确key,则正常发送接受,如果

    setMandatory

    设置为false,则匹配不到的消息直接被丢弃!

    还可以直接使用备份交换器更方便!

    只要配置即可,注意,这里如果之前配置错了,要么重新删除交换器,要么解绑,否则不起作用

    配置:

        //备份交互器
        @Bean
        public FanoutExchange unrouteExchange(){
            return new FanoutExchange("unrouteExchange",true,false);
        }
        //创建备份交互器与备份交互器队列
        @Bean
        public Queue unrouteQueue(){
            return new Queue("unrouteQueue",true);
        }
        //绑定备份交互器与备份队列,不需要指定key
        @Bean
        Binding bindingUnRouteExchangeMessages() {
            return BindingBuilder.bind(unrouteQueue()).to(unrouteExchange());
        }
        //创建消息队列
        @Bean
        public Queue testQueue(){
            //boolean表示消息是否持久化
            return new Queue("testQueue",true);
        }
        //创建交换器
        @Bean
        public DirectExchange exchange(){
            // 指定此交换器的备份交互器,存储没有被路由的消息
            Map<String, Object> args = new HashMap<>();
            args.put("alternate-exchange", "unrouteExchange");
            return new DirectExchange("exchange",true,false,args);
        }
    
        //通过指定key绑定队列与交换器
        @Bean
        Binding bindingExchangeMessages() {
            return BindingBuilder.bind(testQueue()).to(exchange()).with("routeKey");
        }
    

      此时再测试会发现消息进入了备份队列:

    这里有个坑点,如果配置错了,即交换器不存在或者交互器没有绑定队列,不会报错,消息会直接丢失

    我之前这里就是配置交互器名称写成了队列的名称,所以消息一直丢失,搞了大半天!!!!一定要认真!

  • 相关阅读:
    3.JavaWeb过滤器/拦截器/监听器及AOP编程的理解
    flex弹性盒里order属性示例
    flex的align-content、align-items的介绍
    flex的justify-content
    flex属性介绍
    flex模式下的导航条示例
    less变量用法讲解
    css变量的引用
    透视图的设置
    图片飞出效果
  • 原文地址:https://www.cnblogs.com/houzheng/p/10259042.html
Copyright © 2011-2022 走看看