PM2托管Node.js应用占用服务器资源过高问题排查求助
Node.js应用PM2托管内存占用过高问题排查与解决
可能的内存占用原因
- 内存泄漏:Node.js应用存在未释放的资源,比如未清理的闭包、累积的全局变量、未移除的事件监听器、第三方库内存泄漏等。重启/重装PM2只是重启进程,泄漏逻辑未修复,内存仍会持续增长。
- Node.js运行时参数未优化:默认64位系统下Node.js堆内存上限约1.4GB,若应用内存接近该值,会触发频繁垃圾回收,导致CPU和内存占用飙升。
- PM2配置缺失:未设置内存阈值自动重启,或日志未配置轮转,大量日志读取/堆积占用资源。
- 应用逻辑不合理:静态资源未委托反向代理处理、内存缓存无过期机制、重复生成未复用数据等,导致内存持续占用。
排查与解决步骤
1. 定位内存泄漏
- 启用Node.js调试模式分析内存快照:
打开Chrome浏览器输入pm2 restart <your-app-name> --node-args="--inspect"chrome://inspect,连接目标进程后,在Memory面板多次抓取内存快照,对比快照中对象的增长情况,定位泄漏源。 - 用
pm2 monit实时监控实例的内存、CPU变化,若请求后内存只升不降,基本可确认存在内存泄漏。
2. 优化Node.js运行参数
针对4GB内存的双核心服务器,给每个PM2实例设置合理的堆内存上限(预留足够系统内存):
pm2 restart <your-app-name> --node-args="--max-old-space-size=1228"
(每个实例分配1.2GB堆内存,双实例总占用约2.4GB,剩余内存留给系统和其他进程)
3. 优化PM2配置
创建或修改PM2配置文件ecosystem.config.js,添加内存监控自动重启和日志轮转:
module.exports = { apps: [{ name: 'your-app', script: './app.js', instances: 2, max_memory_restart: '1.5G', // 实例内存超过1.5GB时自动重启 log_date_format: 'YYYY-MM-DD HH:mm:ss', error_file: './logs/err.log', out_file: './logs/out.log', log_file: './logs/combined.log', merge_logs: true, log_rotate: { max_size: '10M', // 单日志文件最大10MB retain: 5 // 保留最近5份日志 } }] };
执行pm2 start ecosystem.config.js应用配置。
4. 修复应用逻辑问题
- 清理全局变量:避免使用未声明的全局变量,及时销毁不再使用的全局对象。
- 移除无用事件监听器:对临时事件监听器,在使用完成后调用
removeListener或removeAllListeners。 - 优化缓存策略:用Redis等外部缓存替代内存缓存;若使用内存缓存,需设置过期清理逻辑(如
setTimeout定时删除)。 - 静态资源委托Nginx处理:配置Nginx反向代理,将静态文件(如JS、CSS、图片)的请求直接由Nginx响应,减少Node.js进程负载。
5. 系统层面排查
- 执行
free -h查看系统内存分配,确认是否有其他进程占用大量内存;用htop实时监控所有进程的资源占用情况。 - 检查Swap配置:若内存不足时Swap频繁被使用,会导致性能下降,可根据需求调整Swap分区大小。
内容的提问来源于stack exchange,提问作者bhupesh shakya
相关产品推荐
相关产品推荐

