应用内存不足

本文介绍在使用消息队列时出现应用内存不足时的一些常见问题及解决方法。

现象

  • 在应用部署的机器上查看内存已消耗完。

  • /{user.home}/logs/sofamq.log 能搜索到 OutOfMemory 关键字。

  • 在消息队列控制台查看目标 Group ID 的消费者状态,堆积量 栏显示消息堆积较多,连接信息 栏显示了各个已连接客户端的消息堆积。通过 Jstack 排查,ConsumeMessageThread_ 线程无消费卡住现象。

可能的原因

默认情况下,客户端的最大消耗内存为 512 MB(Group ID 订阅的所有 Topic 缓存总和),且最多会给每个 Topic 的每个队列缓存 1000 条消息。假设每个 Topic 的队列数是 16 个(集群 2 主 2 备,每台 Broker 上 8 个队列),该 Topic 下单条消息平均大小为 64 KB,那么最终该 Topic 在客户端缓存的消息 Size 为 16×1000×64 KB = 1 GB。如果用户同时订阅了 8 个 Topic 都在客户端内存缓存消息,最终占用内存将超过用户的 JVM 配置,导致 OOM。

解决方案

  1. 确认应用依赖的 ons-client 版本。

  2. 根据应用机器的内存使用情况给对应的 ConsumerBean 设置com.alipay.sofa.sofamq.client.PropertyKeyConst#MAX_CACHED_MESSAGE_SIZE_IN_MI_B 参数自行定义最大消耗内存(范围在 16 MB ~ 2048 MB)。

  3. 重启应用。

结果验证

  • /{user.home}/logs/sofamq.logOutOfMemory 关键字不再出现。

  • 登录消息队列控制台查看消费者状态,看到实时消费速度上升,同时堆积量下降。