You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring-RabbitMQ内存泄漏排查:PublisherCallbackChannelImpl listeners堆积求助

问题分析与解决方案

原因判定:确实是内存泄漏问题

你的场景完全符合内存泄漏特征:

  • 采用原型模式的RabbitTemplate每次发送消息都会生成新实例,只要你的应用启用了**发布确认(publisher confirms)或消息退回(publisher returns)**功能(哪怕只是代码中设置了confirmCallback/returnCallback),每个新实例都会在PublisherCallbackChannelImpl的listeners集合里注册一个回调对象。
  • 在你使用的2.2.17.RELEASE版本中,PublisherCallbackChannelImpl没有实现listeners的主动移除逻辑,这些回调对象会被listeners强引用——哪怕原型RabbitTemplate实例本身被丢弃,回调也无法被GC回收。日积月累,listeners会膨胀到占用大量内存,直接导致性能下降。

解决办法

1. 切换为单例RabbitTemplate(优先推荐)

RabbitTemplate是线程安全的,Spring官方明确建议使用单例模式。直接移除原型作用域的配置(比如@Scope("prototype"))即可。
如果之前用原型是为了动态修改exchange、routingKey这类参数,完全可以在每次发送消息前调用setExchange()、setRoutingKey()来调整,不需要新建实例。

2. 必须用原型时手动清理回调

如果业务场景确实需要保留原型模式,一定要在RabbitTemplate实例用完后做清理:

  • 手动调用setConfirmCallback(null)和setReturnCallback(null),触发回调从listeners中移除的逻辑;
  • 或者直接调用destroy()方法,这个方法会自动清理所有已注册的回调,避免内存堆积。

3. 升级spring-rabbit版本

后续的spring-rabbit版本(2.3.x及以上)修复了这个内存泄漏问题,优化了回调的注册与回收机制。如果条件允许,可以升级Spring Boot版本(比如到2.4.x及以上),对应的spring-rabbit会同步升级,从根源上解决这个问题。

内容的提问来源于stack exchange,提问作者Jason Wen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:17:18