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

Puma Docker容器内存使用后无法释放问题求助

Rails Puma集群模式内存持续增长导致容器重启

我们的Rails应用采用Puma集群模式,配置为3个worker、5个线程。容器启动后,Puma worker的内存占用率快速上升,一段时间后增速放缓但仍逐步增长;当内存占用达到100%时,容器会停止并重启。

内存使用率图表:
内存使用率图表


排查与解决方案

1. 定位内存泄漏根源

  • 用derailed_benchmarks快速检测:
    安装gem:gem 'derailed_benchmarks', group: :development
    运行命令:bundle exec derailed exec perf:mem,它会追踪对象分配情况,找出持续增长的对象类型,精准定位泄漏点。
  • 结合memory_profiler做请求级分析:在特定请求中插入内存追踪代码,查看哪些对象未被回收。

2. 优化Puma配置,主动释放内存

  • 启用worker定期重启:在config/puma.rb中添加以下配置,让Puma自动重启worker避免内存累积:
    worker_timeout 3600 # 每小时重启一次worker
    preload_app!
    
    on_worker_boot do
      # 重启worker时重建必要连接
      ActiveRecord::Base.establish_connection
      Rails.cache.reset if defined?(Rails.cache)
    end
    
  • 调整worker/线程配比:如果单worker内存增长过快,可尝试减少worker数量(如2个)或降低线程数(如3个),避免线程竞争导致的资源未释放问题。

3. 排查常见泄漏场景

  • 资源未释放:用lsof -p <worker_pid>检查是否有未关闭的数据库连接、Redis连接或文件句柄。
  • 全局/类变量滥用:避免用@@开头的类变量存储动态数据,这类数据会在worker生命周期内持续累积。
  • 第三方gem问题:排查近期新增的gem,尤其是处理文件、网络请求的依赖,移除后观察内存变化验证是否为gem泄漏。
  • 缓存无过期:检查Rails缓存配置,确保缓存数据设置了合理的过期时间,防止缓存溢出。

4. 容器层面的兜底策略

  • 使用puma_worker_killer实现内存阈值触发重启:
    安装gem:gem 'puma_worker_killer'
    配置config/puma.rb:
    require 'puma_worker_killer'
    
    # 每小时滚动重启worker,避免服务中断
    PumaWorkerKiller.enable_rolling_restart(3600)
    # 内存占用达90%时自动重启worker
    PumaWorkerKiller.config do |config|
      config.ram = 1024 # 容器可用内存(单位:MB,根据实际调整)
      config.percent_usage = 0.9
      config.frequency = 5 # 每5秒检查一次内存
    end
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:55:26