问题描述
我正在尝试以排他模式将新队列添加到现有侦听器,但是出现问题。 代码:
@GetMapping(value = "/consumer")
public void consumer() {
Set<String> queue = new HashSet<>(Arrays.asList("Test queue1","Test queue2","Test queue3"));
// for (int i = 0; i < 10; i++) {
addQueuetoListener("Test container1",queue);
// }
}
public void addQueuetoListener(String containerId,String queueName) {
SimpleMessageListenerContainer listener = (SimpleMessageListenerContainer)
rabbitListenerEndpointRegistry.getListenerContainer(containerId);
if (Objects.nonNull(listener)) {
String[] queueNames = listener.getQueueNames();
System.out.println("Queue Names: " + Arrays.toString(queueNames) + " going to Add: " + queueName);
System.out.println("search result for queue name: " + queueName + " -->" + Arrays.binarySearch(queueNames,queueName));
//do not add same queue name to listener
if (Arrays.binarySearch(queueNames,queueName) < 0) {
System.out.println("Adding queue: " + queueName);
listener.addQueueNames(queueName);
System.out.println("added queue: " + queueName);
}
}
}
public void addQueuetoListener(String containerId,Set<String> queueName) {
for (String queue : queueName) {
addQueuetoListener(containerId,queue);
}
}
兔子监听器代码:
@RabbitListener(id = "Test container1",queues = "#{rabbitMQConsumer.getEntriesQueueName()}",containerFactory = "consumerBatchContainerFactory")
public void receiveMessageBatch(List<Message> messages) throws InterruptedException,IOException {
for (Message message : messages) {
Thread.sleep(30000);
// ObjectMapper jsonObjectMapper = new ObjectMapper();
// Employee employee = jsonObjectMapper.readValue(Arrays.toString(message.getBody()),Employee.class);
String queueName = (String) message.getMessageProperties().getHeaders().get("queueName");
System.out.println("RabbitMQConsumer.receiveMessage QueueName:" + queueName);
// System.out.println("Recieved Message From RabbitMQ: " + employee + " QueueName:"+ queueName);
}
}
public List<String> getEntriesQueueName() {
return Collections.emptyList();
// return Arrays.asList("Test queue1","Test queue3");
}
错误:当我设置listener.setIsExclusive(true);
Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=403,reply-text=ACCESS_REFUSED - queue 'Test queue3' in vhost 'my_vhost' in exclusive use,class-id=60,method-id=20)
甚至尝试在Rabbitlistener上设置独家设置
@RabbitListener(id = "Test container1",containerFactory = "consumerBatchContainerFactory",exclusive = true)
但有相同的错误。
代码参考:https://github.com/rajat-g/SpringBootRabbitMQConsumer
解决方法
有一个bug in the listener container when you call addQueueNames
,我们最终要回收消费者多次,这是一场竞赛-我们不等待消费者被取消。
改为使用listener.addQueues(new Queue(queueName));
。
此外,我将setExclusive
移到了容器工厂bean ...
factory.setContainerCustomizer(container -> container.setExclusive(true));