队列 messages_unacknowledged 一直等于投递总量,ready 反而在降,消费者列表里连接看起来完全正常。日志里能对上时间点,这种反而好排。

消费端取到消息后异常退出或者漏写 ack,自动确认又没开,消息只能挂在 unacked 上,等连接断开才回到队列里。这一点先确认清楚,后面就不用反复试。

rabbitmqctl list_queues name messages_unacknowledged
# 消费端
channel.basicAck(deliveryTag, false);
channel.basicNack(deliveryTag, false, false);

围绕「RabbitMQ 消息未确认」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。

临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

处理上按这个顺序:消费方法用 finally 保证 ack 或 nack 一定走一次;失败统一走 nack 并投进死信队列 不要静默丢弃;给消费者设处理超时 避免线程长期占住通道。

结果对不对很好判断,unacked 回落到 0 附近,队列 ready 随消费正常往下走。

作者 9823189