一台八核十六 G 的 RabbitMQ 3.9 上,订单队列 ready 只有几百,unacked 稳定在十万,消费者进程在跑但业务没有进展,也不报错。
一开始怀疑是「消息没设 TTL,堆积后一直占内存不释放」,查了一圈,方向不对。
把日志和配置对完,能解释这个现象的基本就这几处。prefetch 设得太大,消息全推到客户端却没处理完。另一种情况是消费逻辑里有阻塞调用,工作线程被卡死。
少数情况下是手写 ack 的异常分支既没 ack 也没 nack。
上来先看队列的 ready 与未确认分布
rabbitmqctl list_queues name messages messages_ready messages_unacknowledged consumers
再往下把 prefetch 降到可处理的量级
rabbitmqctl list_channels connection number prefetch_count
接着检查消费者连接与信道状态
rabbitmqctl list_consumers queue_name ack_required prefetch_count
末了处理完积压后确认队列回落
rabbitmqctl list_queues name messages messages_unacknowledged
这台环境是别人交接的,不少默认值被动过,只能一项项核。
恢复的判定其实很直接。prefetch 调到二十后 unacked 降到两百以内,ready 开始稳定下降,订单状态不再滞后于支付。
补一句。unacked 高说明消息到了客户端却没确认,调大 prefetch 只会让积压更隐形;异常路径也要有 ack 或 nack。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
