性能调优

What — 是什么

性能调优是通过压测、profiling 和监控定位 Node.js 应用的性能瓶颈,并进行针对性优化的过程。

核心概念:

  • 压力测试:用 autocannon/k6/artillery 模拟高并发请求,测量 QPS/延迟/P99
  • 内存泄漏process.memoryUsage() 监控 + heapdump 定位持续增长的对象
  • 事件循环延迟perf_hooks.monitorEventLoopDelay 检测主线程阻塞
  • 火焰图--prof + --prof-process 或 clinic.js 生成 CPU 火焰图
  • profiling:V8 的 CPU/内存性能分析,node --inspect + Chrome DevTools
  • Cluster 调优:多进程 + 连接池 + 负载均衡

关键特性:

  • 事件循环延迟 > 100ms 说明有阻塞操作
  • 火焰图可视化展示 CPU 时间花在哪里
  • clinic doctor 自动诊断性能问题

Why — 为什么

适用场景:

  • API 响应慢(P99 超过 1 秒)
  • 内存持续增长疑似泄漏
  • 高并发下 QPS 上不去
  • 启动时间长

How — 怎么用

代码示例

# 压力测试
npx autocannon -c 100 -d 30 http://localhost:3000/api/users

# CPU profiling
node --prof app.js
node --prof-process isolate-*.log > profile.txt

# clinic.js 诊断
npx clinic doctor -- node app.js
# 生成 HTML 报告

# 事件循环延迟监控
const { monitorEventLoopDelay } = require('perf_hooks');
const histogram = monitorEventLoopDelay({ resolution: 20 });
histogram.enable();
setInterval(() => {
    if (histogram.percentile(99) > 100) {
        console.warn('事件循环延迟过高:', histogram.percentile(99));
    }
}, 5000);

// 内存监控
setInterval(() => {
    const { heapUsed, rss } = process.memoryUsage();
    if (heapUsed > 500 * 1024 * 1024) {
        const v8 = require('v8');
        v8.getHeapSnapshot().pipe(require('fs').createWriteStream(`heap-${Date.now()}.heapsnapshot`));
    }
}, 30000);

常见问题与踩坑

问题原因解决方案
P99 延迟高少量慢请求拉高排查慢查询/外部 API 超时
QPS 上不去单进程瓶颈Cluster 模式 + 连接池
内存持续增长事件监听器/闭包泄漏heapdump 对比分析
启动慢大量同步 require延迟加载/ESM lazy import

最佳实践

  • 上线前压测,确定 QPS 基线和 P99 延迟
  • 监控事件循环延迟和内存使用
  • 用 clinic.js 自动诊断性能问题
  • 数据库查询加索引 + 连接池调优
  • Cluster 模式利用多核

面试题

Q1: Node.js 性能调优的常见手段?

① Cluster 多进程——利用多核提升吞吐;② 连接池——复用数据库/HTTP 连接;③ 缓存——Redis 缓存热点数据;④ 流式处理——Stream 处理大数据;⑤ 异步化——CPU 密集任务 offload 到 Worker Threads;⑥ 事件循环监控——检测阻塞并拆分任务;⑦ 压缩——gzip/brotli 减少网络传输;⑧ 索引——数据库查询优化。

Q2: 如何定位 Node.js 内存泄漏?

步骤:① process.memoryUsage() 确认 heapUsed 持续增长;② 两个时间点生成 heapdump(v8.getHeapSnapshot());③ Chrome DevTools Memory 面板加载两个快照;④ Comparison 视图找到增长的构造函数;⑤ 查看 Retainers 追踪引用链;⑥ 定位代码中持有引用的对象(未移除的事件监听器/全局 Map/闭包引用)。


相关链接: