Ejabberd 17.12版本内存泄漏问题求助(BOSH协议MUC聊天场景)
排查Ejabberd 17.12内存泄漏的实用方案
我之前维护Ejabberd集群时,刚好碰到过类似版本+MUC+BOSH场景下的内存泄漏问题,结合你的配置和使用方式,给你梳理几个落地的排查和解决方向:
1. 优先考虑版本升级(最有效的治本方案)
Ejabberd 17.12是2017年底的版本,后续的18.x、19.x以及更新版本修复了大量内存泄漏bug——尤其是mod_muc和mod_bosh模块里的内存残留问题。如果业务允许,建议直接升级到稳定的新版本(比如最新的23.x系列),这能解决绝大多数已知的内存泄漏问题。
2. 排查非持久化MUC房间的残留
你用REST API创建非持久化房间,理论上最后一个用户离开后房间应该自动销毁,但如果BOSH连接异常断开(比如客户端强制退出、网络波动),可能导致房间状态没有正确更新,变成"僵尸房间"占用内存:
- 用命令
ejabberdctl list_muc_rooms查看当前存在的房间,检查是否有大量无人使用的残留房间; - 调整
mod_muc的配置,确保自动销毁逻辑生效:mod_muc: auto_destroy_on_empty: true auto_destroy_timeout: 600 # 空房间10分钟后自动销毁,可根据业务调整 - 如果发现大量僵尸房间,用
ejabberdctl destroy_room <room_name> <host>手动清理。
3. 检查高风险模块的配置
你启用的模块里,几个容易引发内存泄漏的点:
- mod_mam(消息归档):如果没有设置归档消息的过期时间,大量历史消息会堆积在内存(或数据库,但内存缓存也会占用资源)。建议配置:
mod_mam: max_age: 864000 # 保留10天的归档消息,到期自动清理 cache_size: 1000 # 限制内存缓存的消息数量 - mod_bosh:BOSH长连接如果没有及时回收,会导致大量会话进程占用内存。调整配置:
mod_bosh: max_inactivity: 300 # 5分钟无活动自动断开连接 max_sessions_per_user: 5 # 限制单个用户的BOSH会话数,防止滥用 - mod_pubsub/mod_push:如果有大量未处理的订阅请求或推送任务,会导致队列堆积。查看日志里是否有相关报错,调整模块的队列大小限制。
4. 用Erlang工具定位泄漏点
如果上面的通用方案没用,需要精准定位内存泄漏的源头:
- 启动Erlang观察者:执行
ejabberdctl observer,打开可视化界面,查看各个进程的内存占用情况——重点关注MUC房间进程(名称包含muc_room)、BOSH会话进程; - 导出进程状态:用
ejabberdctl dump导出所有进程的状态,分析哪些进程持有大量内存对象; - 开启内存监控日志:在
ejabberd.yml里设置log_level: debug,并添加内存监控配置,定时记录内存使用情况,便于追踪增长趋势。
5. 优化REST API的房间管理逻辑
虽然非持久化房间会自动销毁,但如果你的业务频繁创建房间,且自动销毁不及时,也会导致内存短期堆积:
- 在聊天会话结束后,主动调用REST API的删除房间接口,确保资源及时释放;
- 检查REST API的调用频率,避免短时间内创建大量不必要的房间。
6. 调整Erlang虚拟机参数
不合理的Erlang VM参数也可能导致内存异常,建议在启动脚本里添加:
+P 100000 # 调整最大进程数,根据业务规模设置 +K true # 启用异步IO,提升并发处理效率 -env ERL_MAX_PORTS 65535 # 提升端口上限,避免BOSH连接耗尽端口
内容的提问来源于stack exchange,提问作者Anup Chaudhari
相关产品推荐
相关产品推荐

