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());
}
}
-
监听消费
javapackage 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为什么我取消绑定了,队列创建也注释了,还能消费呢?于是我把消费也注释了
javapackage 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队列都不要了,直接删除即可