Rabbitmq扇形队列取消绑定交换机之后任然接收消息问题
Rabbitmq扇形队列取消绑定交换机之后任然接收消息问题
伪代码
-
申明队列及绑定关系
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 上* 因为是扇型交换机, 路由键无需配置,配置也不起作用*/@Beanpublic Queue queueA() {return new Queue("fanout.A1");}@Beanpublic Queue queueB() {return new Queue("fanout.B1");}@Beanpublic Queue queueC() {return new Queue("fanout.C1");}@BeanFanoutExchange fanoutExchange() {return new FanoutExchange("fanoutExchange1");}@BeanBinding bindingExchangeA() {return BindingBuilder.bind(queueA()).to(fanoutExchange());}@BeanBinding bindingExchangeB() {return BindingBuilder.bind(queueB()).to(fanoutExchange());}@BeanBinding bindingExchangeC() {return BindingBuilder.bind(queueC()).to(fanoutExchange());}} -
监听
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 {@AutowiredRabbitTemplate 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队列我业务中用不到了,那就把写的地方拿掉就好了,于是有了以下代码
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");// }@Beanpublic Queue queueB() {return new Queue("fanout.B1");}@Beanpublic Queue queueC() {return new Queue("fanout.C1");}@BeanFanoutExchange fanoutExchange() {return new FanoutExchange("fanoutExchange1");}// @Bean// Binding bindingExchangeA() {// return BindingBuilder.bind(queueA()).to(fanoutExchange());// }@BeanBinding bindingExchangeB() {return BindingBuilder.bind(queueB()).to(fanoutExchange());}@BeanBinding bindingExchangeC() {return BindingBuilder.bind(queueC()).to(fanoutExchange());}}
-
监听消费
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 {@AutowiredRabbitTemplate 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为什么我取消绑定了,队列创建也注释了,还能消费呢?于是我把消费也注释了
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 {@AutowiredRabbitTemplate 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队列都不要了,直接删除即可
