队列 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 随消费正常往下走。
