RabbitMQ 消费者内存暴涨防护:未 ACK 消息堆积撑爆 JVM?Prefetch 限制 + 自动降级策略!
隔壁组一个 RabbitMQ 消费者服务,每隔几天就 OOM 重启一次。查了 heap dump,发现 Delivery 对象占了 80% 的堆内存——全是未 ACK 的消息。根因是他们用的是默认的自动 ACK,后来改成了手动 ACK 防止消息丢失,但忘了设 prefetch。RabbitMQ 一股脑把所有消息都推给了 Consumer,Consumer 处理不过来,消息在堆内存里越堆越多,直到撑爆。 RabbitMQ 的 Push 模式有个很容易忽略的坑:如果你不设 prefetch,Broker 会用最快的速度把所有消息推给 Consumer。 Consumer 处理慢了,消息就在堆内存里排队等处理。每条消息至少占几百字节,10 万条消息就是几十 MB,轻松打满 JVM。 今天聊聊怎么用 prefetch 限流和自动降级,让 Consumer 不会把自己撑死。 问题出在哪:Push 模式的无限制投递 RabbitMQ 默认的行为是:Consumer 一连接上,Broker 就把当前队列里所有的消息一口气推过去。Consumer 处理不过来没关系——消息已经在你的 JVM 堆里了。....