Spring 使用 AMQP 和 RabbitMQ,使用可选的 x-dead-letter-exchange 进行排队

Spring with AMQP and RabbitMQ, queue with optional x-dead-letter-exchange

我在 RabbitMQ 中创建了一个现有队列。它可以使用或不使用 x-dead-letter-exchange 参数创建。我正在使用 RabbitTemplate 在 Spring 中创建此队列的使用者。当我声明队列时,我不想指定 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;
}

这工作正常,但是当队列的创建者决定不使用死信功能时,我看到以下错误:

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'

消息有点长,它继续告诉我哪一方有哪一方x-dead-letter-exchange(none或交易所名称)。我尝试了不同的组合(例如,使用交换创建队列而不在 Spring 中指定它,或者创建没有交换的队列并在 Spring 中指定它),只是为了看到这个的不同变体消息。

如何声明队列以便它只接受队列中已设置的任何参数?

正如你在spring docs中看到的那样:The RabbitMQ broker will not allow declaration of a queue with mismatched arguments.,所以你不能这样做。
在 RabbitMQ Java API 中有一个检查队列是否已经存在的方法:queueDeclarePassive

如果 Spring AMQP API 提供了类似的功能,您可以在尝试声明队列之前使用它。

是的,可能的原因是 - 如果您手动声明了一些队列,然后您的程序(代码中的客户端)尝试创建一个队列(基于您在代码中的设置),那么您会收到此错误。其背后的原因是当您的代码(客户端应用程序)试图访问一个队列时。它从服务器收到一个信号,表明连接不可用。

解决这个问题

  • 删除所有你手动创建的队列,让客户端程序自己创建。
  • 如果你在删除队列时遇到问题,因为里面有数据,或者因为某些原因,你想维护它,手动创建一个队列,把所有要删除的队列数据移动到里面通过队列的 "Move" 选项卡。

Yes.This 当您在 rabbitMQ 中手动创建交换器或队列然后您的应用程序尝试创建其他 one.And 它会发现相同的队列或具有不同的交换器 properties/configuration 所以它显示配置不匹配。

解决方案:

只允许您的应用程序创建交换器和队列。

希望对您有所帮助。

发件人:https://github.com/jondot/sneakers/issues/121

Try completing all the messages in the queue, delete the queue, then try and re-declare it with the code that failed above. I think you'll find this particular error goes away