Java Spring使用AMQP和RabbitMQ,队列使用可选的x死信交换
我在RabbitMQ中创建了一个现有队列。它可以使用或不使用Java Spring使用AMQP和RabbitMQ,队列使用可选的x死信交换,java,spring,rabbitmq,amqp,spring-amqp,Java,Spring,Rabbitmq,Amqp,Spring Amqp,我在RabbitMQ中创建了一个现有队列。它可以使用或不使用x-dead-letter-exchange参数创建。我正在Spring中使用RabbitTemplate创建此队列的使用者。声明队列时,我不想指定x-dead-letter-exchange参数。我想模板,以某种方式计算它自己或不关心。我从消费者处抛出AmqpRejectAndDontRequeueException,以指示错误消息,但我希望队列的创建者负责决定是否为被拒绝的消息创建交换和队列 下面是我在Spring中声明队列的bea
x-dead-letter-exchange
参数创建。我正在Spring中使用RabbitTemplate创建此队列的使用者。声明队列时,我不想指定x-dead-letter-exchange
参数。我想模板,以某种方式计算它自己或不关心。我从消费者处抛出AmqpRejectAndDontRequeueException
,以指示错误消息,但我希望队列的创建者负责决定是否为被拒绝的消息创建交换和队列
下面是我在Spring中声明队列的bean:
@Bean
Queue queue() {
Map<String, Object> args = new HashMap<>();
// set the queue with a dead letter feature
args.put("x-dead-letter-exchange", REJECTED_EXCHANGE);
args.put("x-dead-letter-routing-key", REJECTED_ROUTING_KEY);
Queue queue = new Queue(Constants.QUEUE_NAME, false, false, false, args);
return queue;
}
@Bean
队列(){
Map args=new HashMap();
//使用死信功能设置队列
参数put(“x死信交换”,拒绝交换);
args.put(“x死信路由密钥”,拒绝路由密钥);
队列=新队列(常数.Queue\u NAME,false,false,false,args);
返回队列;
}
这很好,但当队列的创建者决定不使用死信功能时,我看到以下错误:
Channel shutdown: channel error; protocol method: #method<channel.close>
(reply-code=406, reply-text=PRECONDITION_FAILED -
inequivalent arg 'x-dead-letter-exchange' for queue 'queueName'
通道关闭:通道错误;协议方法:#方法
(回复代码=406,回复文本=前提条件_失败-
队列“queueName”的参数“x死信交换”不等价
消息稍微长了一点,它继续告诉我哪一方有whichx-dead-letter-exchange
(无或交换名称)。我尝试了不同的组合(例如,使用exchange创建队列,但没有在Spring中指定它,或者在没有exchange的情况下创建队列,并在Spring中指定它),仅查看此消息的不同变体
如何声明队列,使其只接受队列中已设置的任何参数?正如您在:中所看到的,RabbitMQ代理将不允许声明参数不匹配的队列。
,因此您不能这样做。在RabbitMQ Java API中,有一种检查队列是否已存在的方法:
queueDeclarePassive
如果Spring AMQP API提供了类似的功能,您可以在尝试声明队列之前使用它。是的,可能的原因是-如果您手动声明一些队列,然后您的程序(代码中的客户端)尝试创建一个队列(基于代码中的设置),则会出现此错误。其原因是您的代码(客户端应用程序)尝试访问一个队列。它从服务器收到一个信号,表示此连接不可用 要解决这个问题,
- 删除您手动创建的所有队列,并让客户端程序自己创建它们
- 如果您在删除队列时遇到问题,因为队列中存在某些数据,或者出于某种原因,您希望维护队列,手动创建一个队列,并通过队列的“移动”选项卡移动其中要删除的所有队列数据
在声明RabbitMQ对象(如队列和交换)时,您必须指定完全相同的参数,RabbitMQ不会为您进行任何类型的参数合并。我不知道如何使用spring进行合并。删除队列并让它们在应用程序启动时创建对我来说是解决问题的