根本原因是Unacked消息长期未确认导致内存占用,而非单纯消息量大;Unacked>50且稳定在100+即表明消费者阻塞或未正确ACK,需检查消费者状态、关闭闲置管理插件并验证惰性队列配置。

内存被消息占满导致集群变慢,根本不是“消息太多”的问题,而是消息没及时落地、又没被消费确认,全卡在内存里——RabbitMQ 默认把 Ready 状态的消息全放内存,Unacked 的消息也还挂在消费者连接上,两者叠加就容易爆内存。
看懂 messages_ready 和 messages_unacknowledged 真实含义
这两个数字不是“队列里有多少消息”,而是“Broker 当前要管多少消息”:
-
messages_ready:已入队但还没发给任何消费者的数量。默认全驻内存,不设惰性队列(x-queue-mode=lazy)时,它涨 10 万条,内存就多吃几百 MB -
messages_unacknowledged:已发给消费者、但还没收到ack的数量。如果消费者卡死、崩溃或没设超时,这些消息就一直挂着,既不重发也不释放,连接资源和内存双占用 - 重点:只要
messages_unacknowledged长期 > 50(尤其稳定在 100+),基本可断定是消费者端任务阻塞或未正确 ack,不是 Broker 性能问题
关掉 rabbitmq_management 插件再查内存
RabbitMQ 内存飙升常被误判为“消息堆积”,实际是管理插件在后台高频拉取 stats 数据,每秒几十次 HTTP 请求 + JSON 序列化,CPU 和内存开销远超消息本身:
RabbitMQ 4.2.3 是 2026 年初发布的重要稳定更新版本,重点修复了 Khepri 元数据存储相关问题,并改进了监控性能。对于使用 Docker、Kubernetes 或微服务架构的开发团队来说,该版本兼容性和稳定性表现较好。
- 运行
rabbitmq-plugins disable rabbitmq_management立刻生效,不用重启 - 观察
erlang memory指标(用rabbitmq-diagnostics memory_breakdown)是否快速回落 - 若回落明显,说明之前压根不是消息问题,而是监控反噬——Web 控制台开着不用时,务必关插件
检查惰性队列(x-queue-mode=lazy)是否真正启用
惰性队列不是“开了就省内存”,必须满足三个条件才生效:
- 队列声明时显式设置
x-queue-mode=lazy(仅声明有效,运行中修改无效) - 队列不能是镜像队列(
x-ha-policy与 lazy 不兼容) - 消息必须处于
ready状态才会写磁盘;一旦被投递成unacked,仍留在内存——所以光开 lazy 不解决 unacked 卡住的问题 - 验证方式:查
rabbitmqctl list_queues name queue_mode,确认目标队列显示lazy而非default
用 rabbitmqctl list_connections 找“假在线真僵死”的消费者
大量 unacked 消息背后,常是消费者进程僵死但 TCP 连接没断,RabbitMQ 还以为它活着,继续往里塞消息:
- 运行
rabbitmqctl list_connections columns=name,recv_oct,send_oct,channels,state - 重点关注
recv_oct(接收字节数)长期不动、state是running但channels数异常高的连接 - 这类连接大概率对应一个卡住的 Celery worker 或 Java Spring AMQP 客户端,需直接 kill 进程并检查日志里的超时/死锁
- 别依赖心跳:AMQP 心跳只保连接不断,不保业务逻辑不卡
真正拖垮集群的,往往不是消息量,而是那些没人管的 unacked 消息和开着不用的管理插件——它们让 RabbitMQ 在替你背锅。


















