远程Ubuntu 16.04 LTS虚拟机中Node.js应用CPU过载问题求助
排查Node.js应用(PM2托管)CPU逐渐过载的方案
我之前帮朋友处理过几乎一模一样的场景——周期性轮询的Node.js应用初期CPU正常,后期直接飙到100%,咱们一步步来拆解问题,找到根源:
第一步:先搞清楚是谁在吃CPU
首先得确认是你的Node.js进程本身导致的CPU飙升,还是系统其他进程搞的鬼:
- 用
htop或者top命令,找到名为node的进程,盯着它的CPU占用看几分钟,确认是不是它在持续攀升。 - 直接用PM2自带的监控:
pm2 monit,这个工具很直观,能实时看到CPU、内存数据,还能快速跳转到日志页面。 - 用Node.js的诊断工具深挖:启动应用时加
--inspect参数(比如pm2 start app.js -- --inspect),然后在本地Chrome浏览器打开chrome://inspect,连接到远程虚拟机的进程,用Performance面板录制10-15分钟的运行数据,就能看到具体是哪些函数在持续占用CPU。 - 嫌手动分析麻烦的话,用
clinic.js工具,安装后跑clinic doctor -- node app.js,它会自动分析CPU和内存使用情况,直接给你指出可能的问题点。
第二步:重点排查轮询逻辑的坑
你的应用是每5分钟轮询股票网站,这类周期性任务最容易踩两个坑:任务堆积和内存泄漏:
- 检查定时器的使用:如果你用的是
setInterval,要注意如果某次轮询的爬取/计算耗时超过5分钟,会导致多个任务同时运行,直接把CPU拉满。建议换成setTimeout递归调用,确保上一次任务彻底完成后再启动下一次:async function pollStockData() { try { // 你的爬取、计算逻辑 await fetchStockInfo(); await processCalculation(); } catch (err) { console.error('轮询出错:', err); } finally { // 不管成功失败,5分钟后再执行下一次 setTimeout(pollStockData, 5 * 60 * 1000); } } // 启动第一次轮询 pollStockData(); - 检查HTTP请求的资源清理:爬取网站时用的是
axios、request还是原生http?如果每次请求都新建实例、不关闭连接,会导致socket堆积,既占内存又耗CPU。比如用axios的话,建议创建全局实例并设置超时和连接关闭:const axios = require('axios').create({ timeout: 10000, // 超时时间,避免请求挂起 headers: { 'Connection': 'close' } // 显式关闭连接 }); - 检查计算逻辑:如果你的计算部分有嵌套循环、未优化的大数据处理,或者不小心写了无限循环,都会导致CPU持续升高。可以在计算函数里加日志,记录每次计算的耗时,看是不是耗时越来越长。
- 排查内存泄漏:如果
pm2 monit显示内存也跟着CPU一起涨,那大概率是内存泄漏。用Chrome DevTools的Memory面板,拍两次堆快照(间隔10分钟),对比看哪些对象一直在增长没被回收——比如全局变量累加数据、重复绑定事件监听器没移除这类问题。
第三步:优化PM2的配置
PM2的一些配置也可能间接影响CPU使用:
- 检查进程模式:如果你的应用是单线程,别用
cluster模式(除非你要利用多核,但先解决过载问题再说)。在ecosystem.config.js里设置exec_mode: 'fork'。 - 加个兜底的自动重启:虽然这是临时方案,但可以避免CPU长时间过载。在配置文件里加:
module.exports = { apps: [{ name: 'stock-app', script: 'app.js', max_memory_restart: '200M', // 内存超过200M自动重启 env: { NODE_ENV: 'production' } }] }; - 看PM2日志找异常:用
pm2 logs stock-app查看有没有报错或警告,比如网络请求失败后无限重试,也会把CPU耗干。
第四步:排查系统和依赖的问题
- 系统层面:用
htop看所有进程的CPU占用,确认是不是有其他系统进程(比如cron任务、系统更新)在抢资源。 - Node.js版本:Ubuntu 16.04自带的Node.js版本可能很旧(比如v4/v6),旧版本有不少已知的性能和内存泄漏问题,建议升级到LTS版本(比如v14或v16,注意兼容你的依赖)。
- 依赖包问题:检查你的依赖有没有已知的性能bug,比如某些爬虫库、计算库在长时间运行后会泄漏内存。用
npm ls看依赖版本,去npm的issues里搜搜有没有类似的CPU/内存问题。
总结
按这个顺序排查:先定位CPU来源,再重点搞轮询逻辑的任务堆积和内存泄漏,然后优化PM2配置,最后查系统和依赖。大概率是定时器用错了,或者HTTP请求/计算逻辑的资源没清理干净导致的。
内容的提问来源于stack exchange,提问作者Adeel Hashmi
相关产品推荐
相关产品推荐

