RabbitMQ:消息保持“未确认";

2022-01-11 00:00:00 rabbitmq amqp message-queue java

我的 Java 应用程序将消息发送到 RabbitMQ 交换器,然后交换器将消息重定向到绑定队列.我将 Springframework AMQP java 插件与 RabbitMQ 一起使用.

My Java application sends messages to RabbitMQ exchange, then exchange redirects messages to binded queue. I use Springframework AMQP java plugin with RabbitMQ.

问题:消息进入队列,但它停留在Unacknowledged"状态,它永远不会变成Ready".

The problem: message comes to queue, but it stays in "Unacknowledged" state, it never becomes "Ready".

可能是什么原因?

推荐答案

Unacknowledged 消息意味着它已被您的消费者读取,但消费者从未向 RabbitMQ 代理返回 ACK 表示它已完成处理它.

An Unacknowledged message implies that it has been read by your consumer, but the consumer has never sent back an ACK to the RabbitMQ broker to say that it has finished processing it.

我对 Spring Framework 插件并不太熟悉,但是在某个地方(对于您的消费者)您将声明您的队列,它可能看起来像这样(取自 http://www.rabbitmq.com/tutorials/tutorial-two-java.html):

I'm not overly familiar with the Spring Framework plugin, but somewhere (for your consumer) you will be declaring your queue, it might look something like this (taken from http://www.rabbitmq.com/tutorials/tutorial-two-java.html):

channel.queueDeclare(queueName, ....)

然后你将设置你的消费者

then you will setup your consumer

bool ackMode = false;
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, ackMode, consumer);

上面的 ackMode 是一个布尔值,通过将其设置为 false,我们明确告诉 RabbitMQ 我的消费者将确认收到的每条消息.如果此标志设置为 true,那么您将不会在 RabbitMQ 中看到 Unacknowledged 计数,而是在消费者读取消息后(即,它已交付给消费者,它将从队列中删除).

ackMode above is a boolean, by setting it to false, we're explicitly saying to RabbitMQ that my consumer will acknowledge each message it is given. If this flag was set to true, then you wouldn't be seeing the Unacknowledged count in RabbitMQ, rather as soon as a consumer has read the message off (i.e it has been delivered to the consumer it will remove it from the queue).

要确认消息,您可以执行以下操作:

To acknowledge a message you would do something like this:

QueueingConsumer.Delivery delivery = consumer.nextDelivery();
//...do something with the message...
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); //the false flag is to do with multiple message acknowledgement

<小时>

如果您可以发布您的一些消费者代码,那么我可能会提供进一步的帮助......但同时看看 BlockingQueueConsumer 具体来说:您将看到的构造函数可以设置 AcknowledgeMode 并采取查看 nextMessage() 这将返回一个 Message 对象,其中包含一个名为 getDeliveryTag() 的方法 这将返回一个 Long ,这是您将在 basicAck 上发回的 ID


If you can post some of your consumer code then I might be able to help further...but in the mean time take a look at BlockingQueueConsumer specifically: the constructor you will see that you can set the AcknowledgeMode and also take a look at the nextMessage() this will return a Message object which contains a method called getDeliveryTag() this will return a Long which is the ID that you would send back on the basicAck

相关文章