RabbitMQ连接数暴涨引发内存溢出,核心是Java侧连接/通道对象在JVM堆内累积与Erlang进程内存膨胀双重叠加;需同步排查Spring AMQP配置(如CachingConnectionFactory缓存失控)、RabbitMQ服务端连接状态(TIME_WAIT残留、进程内存占比过高)、TLS/插件开销及GC失效问题。

Java 应用中 RabbitMQ 连接数暴涨引发内存溢出,核心不是消息堆积,而是连接和通道对象在 JVM 堆内持续累积,同时底层 Erlang 进程也在消耗系统内存。排查要分两层:Java 侧(Spring AMQP)和 RabbitMQ 服务侧,缺一不可。
查 Java 侧连接/通道是否失控
Spring AMQP 的 RabbitTemplate 本身不泄漏,但背后 CachingConnectionFactory 配置不当会直接导致 AMQConnection 和 ChannelN 实例暴增:
- 用
jmap -histo:live <pid>查堆中com.rabbitmq.client.impl.AMQConnection和com.rabbitmq.client.impl.ChannelN数量是否随时间阶梯式上涨 - 检查 JMX 中
CachingConnectionFactory的Channels属性值是否长期不回落,尤其关注高并发后是否滞留高位 - 确认是否手动 new 多个
RabbitTemplate或多个CachingConnectionFactoryBean(未加@Scope("singleton")),每个实例都维护独立缓存 - 验证
spring.rabbitmq.cache.channel.size是否设得过大(生产建议 ≤10),或干脆未配置上限(默认 25,短时突增易突破)
查 RabbitMQ 服务端连接状态异常
Java 侧连接未释放,会反映为 RabbitMQ 上大量 “活着但不干活” 的连接,进一步拖垮 Erlang VM 内存:
- 执行
rabbitmqctl list_connections columns=pid,recv_cnt,send_cnt,channels,state,重点关注state为starting、blocked或长时间无收发(recv_cnt/send_cnt几乎不变)的连接 - 运行
rabbitmqctl eval 'erlang:memory(processes).'看进程内存占比;若接近erlang:memory(used)总量,说明是连接进程膨胀主导 - 在宿主机跑
netstat -an | grep :5672 | grep TIME_WAIT | wc -l,若远超正常并发量(如 >1000),说明客户端断连未优雅关闭,TIME_WAIT 残留占资源 - 检查
rabbitmqctl status中processes和run_queue,若run_queue > 1000,Erlang 调度已过载,GC 效率下降
查 TLS 和插件是否加重负担
启用 TLS 或开启过多管理插件,会在每次建连时引入额外开销,放大连接暴涨的影响:
立即学习“Java免费学习笔记(深入)”;
- 若启用了 TLS,确认证书链是否过长、是否开启 OCSP 装订——这些都会在握手阶段缓存大量 SSL 对象,且不易被及时回收
- 执行
rabbitmq-plugins list,禁用非必需插件(如rabbitmq_tracing),尤其避免在生产环境长期开启 trace - 观察
rabbitmqctl eval 'erlang:memory(binary).',若 binaries 内存占比异常高,可能与 TLS 缓存或大消息体有关
查内存水位与 GC 是否失效
RabbitMQ 自身内存告警机制一旦触发,会主动阻塞连接,但若 GC 卡死,内存就只涨不降:
- 进入 RabbitMQ Management UI → Nodes → 点击主机名 → Memory Details,重点看
Runtime Used和GC bytes reclaimed曲线是否为零线——为零说明 GC 完全停滞 - 检查
rabbitmqctl status输出中的{vm_memory_high_watermark, N},确认是否被误设为 0(完全关闭内存保护)或过高(如 0.8) - 排查是否有外部工具(如某些命令行加密代理、安全审计软件)干扰 Erlang VM 的信号处理或内存分配,曾有案例证实这类工具直接导致 GC 失效


















