RabbitMQ:消息仍为“未确认”

我的Java应用程序向RabbitMQ交换发送消息,然后交换重定向消息到绑定队列。 我在RabbitMQ中使用Springframework AMQP java插件。

问题:消息进入队列,但它保持“未确认”状态,它永远不会变为“就绪”。

可能是什么原因?

未确认消息意味着消费者已经读取了消息,但消费者从未向RabbitMQ代理发回ACK以表示已完成处理。

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

channel.queueDeclare(queueName, ....) 

那么你将设置你的消费者

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

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

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

 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

只是为了让消息保持在未确认状态的另一个可能原因加上我的2美分,即使消费者确保使用basicAck方法 –

有时,具有打开的RabbitMQ连接的进程的多个实例保持运行,其中一个实例可能导致消息陷入未确认状态,从而阻止消费者的另一个实例重新获取此消息。

您可以访问RabbitMQ管理控制台(对于本地计算机,这应该在localhost:15672上可用),并检查多个实例是否获得该通道,或者是否只有一个实例当前处于活动状态:

RabbitMQ连接

找到冗余运行任务(在本例中为java)并终止它。 删除流氓进程后,您应该会看到该消息再次跳转到Ready状态。