Rabbitmq扇形队列取消绑定交换机之后任然接收消息问题

Rabbitmq扇形队列取消绑定交换机之后任然接收消息问题

伪代码

申明队列及绑定关系

java 复制代码
package com.cdn.mqprovider;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutRabbitProviderConfig {

        /**
         * 创建三个队列 :fanout.A   fanout.B  fanout.C
         * 将三个队列都绑定在交换机 fanoutExchange 上
         * 因为是扇型交换机, 路由键无需配置,配置也不起作用
         */

        @Bean
        public Queue queueA() {
            return new Queue("fanout.A1");
        }

        @Bean
        public Queue queueB() {
            return new Queue("fanout.B1");
        }

        @Bean
        public Queue queueC() {
            return new Queue("fanout.C1");
        }

        @Bean
        FanoutExchange fanoutExchange() {
            return new FanoutExchange("fanoutExchange1");
        }

        @Bean
        Binding bindingExchangeA() {
            return BindingBuilder.bind(queueA()).to(fanoutExchange());
        }

        @Bean
        Binding bindingExchangeB() {
            return BindingBuilder.bind(queueB()).to(fanoutExchange());
        }

        @Bean
        Binding bindingExchangeC() {
            return BindingBuilder.bind(queueC()).to(fanoutExchange());
        }
    }

监听

java 复制代码
package com.cdn.mqprovider.api;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 蔡定努
 * 2025/10/29 17:56
 */
@RestController
public class A {

    @Autowired
    RabbitTemplate rabbitTemplate;


    /**
     * @author 蔡定努
     */
    @GetMapping("send")
    public void send() {
        rabbitTemplate.convertAndSend("fanoutExchange1", "", "消息1");
    }





    // -------------------消费----------------------
    @RabbitListener(queues = "fanout.A1",ackMode = "AUTO")
    public void processm(String testMessage) {
        System.out.println("fanout.A1消费者收到消息  : " + testMessage);
    }

    @RabbitListener(queues = "fanout.B1",ackMode = "AUTO")
    public void processmb(String testMessage) {
        System.out.println("fanout.B1消费者收到消息  : " + testMessage);
    }

    @RabbitListener(queues = "fanout.C1",ackMode = "AUTO")
    public void processmc(String testMessage) {
        System.out.println("fanout.C1消费者收到消息  : " + testMessage);
    }

}

测试

调用send接口

复制代码
fanout.C1消费者收到消息  : 消息1
fanout.A1消费者收到消息  : 消息1
fanout.B1消费者收到消息  : 消息1

调整

此时我有一个需求,fanout.A1队列我业务中用不到了,那就把写的地方拿掉就好了,于是有了以下代码

申明队列及绑定关系

java 复制代码
package com.cdn.mqprovider;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutRabbitProviderConfig {

        /**
         * 创建三个队列 :fanout.A   fanout.B  fanout.C
         * 将三个队列都绑定在交换机 fanoutExchange 上
         * 因为是扇型交换机, 路由键无需配置,配置也不起作用
         */

        // @Bean
        // public Queue queueA() {
        //     return new Queue("fanout.A1");
        // }

        @Bean
        public Queue queueB() {
            return new Queue("fanout.B1");
        }

        @Bean
        public Queue queueC() {
            return new Queue("fanout.C1");
        }

        @Bean
        FanoutExchange fanoutExchange() {
            return new FanoutExchange("fanoutExchange1");
        }

        // @Bean
        // Binding bindingExchangeA() {
        //     return BindingBuilder.bind(queueA()).to(fanoutExchange());
        // }

        @Bean
        Binding bindingExchangeB() {
            return BindingBuilder.bind(queueB()).to(fanoutExchange());
        }

        @Bean
        Binding bindingExchangeC() {
            return BindingBuilder.bind(queueC()).to(fanoutExchange());
        }
    }
  1. 监听消费

    java 复制代码
    package com.cdn.mqprovider.api;
    
    import org.springframework.amqp.rabbit.annotation.Exchange;
    import org.springframework.amqp.rabbit.annotation.Queue;
    import org.springframework.amqp.rabbit.annotation.QueueBinding;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 蔡定努
     * 2025/10/29 17:56
     */
    @RestController
    public class A {
    
        @Autowired
        RabbitTemplate rabbitTemplate;
    
    
        /**
         * @author 蔡定努
         */
        @GetMapping("send")
        public void send() {
            rabbitTemplate.convertAndSend("fanoutExchange1", "", "消息1");
        }
    
    
    
    
    
        // -------------------消费----------------------
        @RabbitListener(queues = "fanout.A1",ackMode = "AUTO")
        public void processm(String testMessage) {
            System.out.println("fanout.A1消费者收到消息  : " + testMessage);
        }
    
        @RabbitListener(queues = "fanout.B1",ackMode = "AUTO")
        public void processmb(String testMessage) {
            System.out.println("fanout.B1消费者收到消息  : " + testMessage);
        }
    
        @RabbitListener(queues = "fanout.C1",ackMode = "AUTO")
        public void processmc(String testMessage) {
            System.out.println("fanout.C1消费者收到消息  : " + testMessage);
        }
    
    }

    测试

    调用send接口

    复制代码
    fanout.C1消费者收到消息  : 消息1
    fanout.A1消费者收到消息  : 消息1
    fanout.B1消费者收到消息  : 消息1

    为什么我取消绑定了,队列创建也注释了,还能消费呢?

    于是我把消费也注释了

    java 复制代码
    package com.cdn.mqprovider.api;
    
    import org.springframework.amqp.rabbit.annotation.Exchange;
    import org.springframework.amqp.rabbit.annotation.Queue;
    import org.springframework.amqp.rabbit.annotation.QueueBinding;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 蔡定努
     * 2025/10/29 17:56
     */
    @RestController
    public class A {
    
        @Autowired
        RabbitTemplate rabbitTemplate;
    
    
        /**
         * @author 蔡定努
         */
        @GetMapping("send")
        public void send() {
            rabbitTemplate.convertAndSend("fanoutExchange1", "", "消息1");
        }
    
    
    
    
    
        // -------------------消费----------------------
        // @RabbitListener(queues = "fanout.A1",ackMode = "AUTO")
        // public void processm(String testMessage) {
        //     System.out.println("fanout.A1消费者收到消息  : " + testMessage);
        // }
    
        @RabbitListener(queues = "fanout.B1",ackMode = "AUTO")
        public void processmb(String testMessage) {
            System.out.println("fanout.B1消费者收到消息  : " + testMessage);
        }
    
        @RabbitListener(queues = "fanout.C1",ackMode = "AUTO")
        public void processmc(String testMessage) {
            System.out.println("fanout.C1消费者收到消息  : " + testMessage);
        }
    
    }

    测试

    调用send接口

    复制代码
    fanout.C1消费者收到消息  : 消息1
    fanout.B1消费者收到消息  : 消息1

看似没有问题了,但是,问题就来了,随着业务的进行,mq报警了,消息堆积

原因

因为fanout.A1在之前就创建了,并且绑定关系也建立了,就算你代码中注释掉了队列申明和绑定关系,mq不会主动去删除对应的队列和绑定关系,但是消费者被注释了,所以就出现消息只进不出的情况,导致对接

解决办法

既然a队列都不要了,直接删除即可

相关推荐
用户8307196840822 天前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者3 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者5 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧6 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖6 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农6 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者6 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀6 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3056 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05096 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式