使用 Spring AQMP Java 客户端,我尝试发布到现有的 RabbitMQ 仲裁队列。
如这个SO答案所示,我的代码使用'quorum'的
x-queue-type
参数定义目标队列:
@Bean
Queue queue(@Value("${spring.rabbitmq.listener.queue.name}") String queueName) {
Queue queue = new Queue(queueName, true, false, false, Map.of("x-queue-type", "quorum"));
queue.setShouldDeclare(true);
return queue;
}
如果队列尚不存在并且 RabbitMQ 管理控制台显示新队列是使用“quorum”类型创建的,则此方法可以正常工作。但是,如果我重新启动应用程序并且队列已经存在,则发布尝试失败并显示消息:
Failed to declare queue: Queue [name=myqueuename, durable=true, autoDelete=false, exclusive=false, arguments={}, actualName=myqueuename], continuing... com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-queue-type' for queue 'myqueuename' in vhost 'myvhost': received none but current is the value 'quorum' of type 'longstr'
当远程队列的定义与本地队列定义不匹配时,会出现此消息。但为什么会发生在这里呢?我已声明队列并将
x-queue-type
设置为“quorum”,并且与远程队列定义匹配。您可以看到日志消息的第一行显示 exclusive=false, *arguments={}*
,这意味着传递给队列构造函数的参数映射将被忽略。
我应该如何定义这个队列,以便它不仅创建仲裁队列,而且还可以发布到它?
我无法重现它。根据您的描述,这是一个简单的 Spring Boot 应用程序:
@SpringBootApplication
public class So77224292Application {
public static void main(String[] args) {
SpringApplication.run(So77224292Application.class, args);
}
@Bean
Queue queue() {
return new Queue("myQueue", true, false, false, Map.of("x-queue-type", "quorum"));
}
@Bean
ApplicationRunner applicationRunner(RabbitTemplate rabbitTemplate) {
return args -> rabbitTemplate.convertAndSend("myQueue", new Random().nextDouble());
}
@RabbitListener(queues = "myQueue")
public void consume(String payload) {
System.out.println("Received: " + payload);
}
}
当代理上没有队列时,会创建队列。发布和消费的数据。 重新启动后,队列就位后,一切仍然按预期工作:随机数据发布和消耗。
也许您还有其他需要与我们分享的内容,以便我们可以在我们这边重现它并找出问题所在。