2022-11-02 05:46:46
分析 Node.js 应用高 CPU 占用率可采用以下方法,涵盖本地开发和生产环境的不同场景:
本地开发环境分析方法使用 Chrome DevTools 进行 CPU 分析
启动应用时添加 --inspect 标志:
node --inspect your-app.js在 Chrome 浏览器访问 chrome://inspect,点击应用下方的 inspect 按钮。
在 DevTools 中选择 Memory 标签页,点击 Record CPU Profile 按钮开始分析。

执行负载测试后停止记录,查看火焰图定位高耗时函数。

命令行工具辅助分析
使用 top 或 htop 快速定位高 CPU 占用的 Node 进程。
通过 ps -aux | grep node 获取进程 PID 后,使用 perf 或 strace 进行底层分析。
按需采集 CPU Profile(推荐)
使用 Node.js 内置 inspector 模块或 inspector-api 包装库,避免全量调试模式的高开销。
示例代码(NestJS 框架):
import { Controller, Post } from '@nestjs/common';import { promisify } from 'util';import Inspector from 'inspector-api';const profileRecordTime = 10000; // 记录时长10秒@Controller('/profile')export class ProfileController { @Post('/cpu') async cpu() { setImmediate(async () => { const inspector = new Inspector({ storage: { type: 'fs' } }); await inspector.profiler.enable(); await inspector.profiler.start(); await promisify(setTimeout)(profileRecordTime); await inspector.profiler.stop(); console.log('CPU profile saved to temp dir'); await inspector.profiler.disable(); }); return true; }}通过 HTTP 端点触发采集:
curl -X POST信号触发采集(无 HTTP 暴露)
监听系统信号(如 SIGUSR1)触发分析:
process.on('SIGUSR1', async () => { const inspector = new Inspector({ storage: { type: 'fs' } }); await inspector.profiler.start(); await promisify(setTimeout)(profileRecordTime); await inspector.profiler.stop();});通过 kill 命令发送信号:
kill -USR1 <node-pid>堆内存分析(辅助排查)
替换 profiler 为 heap 模块采集堆快照:
process.on('SIGUSR2', async () => { const inspector = new Inspector({ storage: { type: 'fs' } }); await inspector.heap.startSampling(); await promisify(setTimeout)(profileRecordTime); await inspector.heap.stopSampling();});触发命令:
kill -USR2 <node-pid>定位热点函数
采集的 .cpuprofile 文件可用 Chrome DevTools 或 speedscope 等工具打开。
火焰图中宽度较大的函数块代表高 CPU 占用。
优化建议
同步阻塞操作:检查是否有未优化的循环或同步 I/O 操作。
事件循环延迟:使用 process.hrtime() 监控事件循环阻塞时间。
内存泄漏:结合堆快照分析对象保留情况。
通过上述方法,可系统化定位 Node.js 应用的高 CPU 占用问题,平衡排查效率与生产环境稳定性。