Ejabberd 17.04集群PubSub阻塞调用超时/响应过慢问题求助
结合你描述的场景——AWS双节点集群、2万+用户订阅4个扁平PubSub节点,且MUC功能正常,我来梳理下可能的原因和具体排查步骤:
可能的核心原因
1. PubSub模块的并发处理能力不足
Ejabberd 17.04的PubSub模块默认进程池配置(pubsub_processes)通常较小(比如默认10-20),面对每个节点数千级的订阅者,大量请求会排队等待空闲进程,直接导致阻塞超时。而MUC的进程模型更偏向于每个房间一个进程,并发处理逻辑更分散,所以没出现瓶颈。
2. 集群同步的性能瓶颈
AWS跨可用区(或跨节点)的网络延迟,加上Ejabberd PubSub依赖Mnesia集群同步订阅者列表、消息状态,一旦同步延迟过高,就会拖慢所有跨节点的PubSub操作。反观MUC,很多场景下消息只需在本地节点广播,同步压力小很多。
3. Mnesia数据库的读写瓶颈
PubSub的订阅数据、节点元数据默认存在Mnesia的disc_copies表中,当订阅量达到数万级时,磁盘IO会成为严重瓶颈。如果Mnesia的内存分配不足,还会触发频繁的swap交换,进一步拖慢操作。而MUC的临时数据(比如在线成员)大多存在内存表,读写更快。
4. CPU/网络资源耗尽
PubSub发布消息时需要遍历所有订阅者并推送,2万+用户的批量推送会瞬间打满CPU或网络带宽。比如每个发布请求要处理5000+订阅者,4核CPU可能无法及时处理并发请求;AWS实例的带宽如果有限,推送大量XMPP消息时会出现拥堵,导致响应超时。
5. 旧版本的已知Bug
Ejabberd 17.04是2017年的版本,存在不少PubSub高并发场景下的Bug,比如进程死锁、资源泄漏、订阅列表查询效率低等问题,这些在后续版本中都有修复,而MUC模块受影响较小。
具体排查步骤
1. 优先查看Ejabberd日志
把ejabberd.yml中的loglevel调到5(调试级别),重启服务后,重点搜索pubsub相关日志:
- 有没有
timeout waiting for response或Mnesia transaction took too long的报错? - 有没有进程阻塞、资源耗尽的提示?
这些日志能直接定位到具体的阻塞环节。
2. 监控服务器核心资源
用Linux工具和AWS CloudWatch监控:
- 用
htop看CPU使用率,是不是ejabberd进程长期占满CPU核心? - 用
free -m检查内存,是否出现swap频繁使用(内存不足的标志)? - 用
iftop或CloudWatch看网络带宽,PubSub发布高峰期是不是跑满了实例带宽? - 用
iostat看磁盘IO,Mnesia所在磁盘的读写延迟是否过高?
3. 检查PubSub配置参数
打开ejabberd.yml,重点核对以下参数:
pubsub_processes: 把默认值(比如10)调大到50-100,提升PubSub的并发处理能力。max_subscribers: 确认每个节点的最大订阅数是否大于实际订阅量(默认可能是1000,你的场景需要调到至少5000)。persistence: 如果允许订阅数据重启后重建,可以临时改成false,测试是否解决问题(排除磁盘IO瓶颈)。
4. 诊断Mnesia集群状态
用Ejabberd命令行工具检查:
- 执行
ejabberdctl mnesia_status,看集群节点间的复制是否正常,有没有同步延迟。 - 执行
ejabberdctl table_info pubsub_subscriptions all,查看订阅表的大小、存储类型(ram_copies还是disc_copies)。如果是disc_copies,可以临时改成ram_copies(需备份数据),测试性能提升效果。
5. 隔离集群影响
临时将集群切换为单节点(停止其中一台服务器),测试2万+订阅下的PubSub操作是否正常:
- 如果单节点正常,说明问题出在集群同步或跨节点网络上,需要优化AWS节点的网络配置(比如放在同一可用区)或调整Ejabberd的Mnesia复制策略。
- 如果单节点仍有问题,说明是单节点的资源或配置瓶颈。
6. 对比MUC与PubSub的性能指标
用ejabberdctl get_metrics查看核心指标:
- 对比
pubsub_publish_time、pubsub_subscribe_time和muc_message_time的平均值,确认PubSub的耗时是否远超MUC。 - 用
ejabberdctl processes查看PubSub进程的状态,是否大量处于waiting或blocked状态。
7. 尝试升级Ejabberd版本
由于17.04版本过于陈旧,建议备份数据后升级到最新稳定版(比如24.x),新版本修复了大量PubSub高并发下的Bug,很多类似问题都能直接解决。
内容的提问来源于stack exchange,提问作者Rakesh Waghela

