Nodejs 性能分析

Node 内置分析器

V8 引擎具有内置分析器, 通过 --prof 运行

Bash
node --prof --no-logfile-per-isolate --log --logfile=myScript.log myScript.js
  • --no-logfile-per-isolate – 每次运行 V8 node 实例时,都称为一次隔离,因为每个 V8 实例的状态都与所有其他实例隔离,并且都分配有一个ID。默认情况下,此 ID包含在日志文件名称中。此参数可告知概要分析器在每次运行时都生成一个日志文件v8.log,并覆盖前一个日志文件。
  • --log – 创建最少量的日志记录(例如,无垃圾回收样本)
  • --logfile=myScript.log – 在当前目录中创建名为 myScript.log 的日志文件。与 --no-logfile-per-isolate 标志结合使用,它可覆盖默认文件名 v8.log

截屏2020-09-21 下午4.18.36.png
难以读懂,可以做该要分析并格式化:

Bash
node --prof-process myScript.log > myScript.log.txt

截屏2020-09-21 下午4.22.04.png
可以整合一下:

Bash
node –prof –no-logfile-per-isolate –log –logfile=myScript.log myScript.js && node –prof-process myScript.log.txt && rm myScript.log

其中首行,tick 表示一段采样时间间隔,默认1000 us (1ms),这段代码用了  127ms

Bash
Statistical profiling result from myScript.log, (127 ticks, 6 unaccounted, 0 excluded).

注意这是 V8 的运行时间
如果改成同步代码,会看到 tick 增加很多,大部分异步代码都不在 V8 线程上运行,而在事件循环(libuv)中运行。

但实际整个程序的运行时间,如果改成异步,可以用 process.hrtime  统计, 会发现异步代码总执行时间更长,原因在于 libuv 的开销

异步编程并不关乎单纯的速度,而是关乎可扩展性

负载分析

所以对于异步任务性能测试,不能仅仅看性能概要,需要做额外的负载测试

Bash
curl -X GET "http://localhost:8080/newUser?username=matt&password=password"
ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password"

最好有图形输出  clinic
clinic 也是启动了一个 Node 进程,用于收集有关其运行方式的信息

  • clinic doctor 用于诊断 Node 应用程序性能问题并提出建议。
  • clinic bubbleprof 用于分析 Node 应用程序中的异步延迟,并生成可视化的延迟气泡图。
Bash
clinic doctor -- node myScript.js
? May Clinic.js report anonymous usage statistics to improve the tool over time? Yes
To generate the report press: Ctrl + C
hello
world
Analysing data
Generated HTML file is file:///Users/albertaz/Documents/learn/Node.js/.clinic/57602.clinic-doctor.html
You can use this command to upload it:
clinic upload .clinic/57602.clinic-doctor

image.png

Bash
➜  Node.js clinic bubbleprof -- node myScript.js
To generate the report press: Ctrl + C
hello
Warning: The code is transpiled, bubbleprof does not support source maps yet.
world
Analysing data
Generated HTML file is file:///Users/albertaz/Documents/learn/Node.js/.clinic/57886.clinic-bubbleprof.html
You can use this command to upload it:
clinic upload .clinic/57886.clinic-bubbleprof

image.png

火焰图分析内存

linux pref

linux 自带的系统性能分析工具, 通过 linux-tools-common 安装
https://github.com/nswbmw/node-in-debugging/blob/master/1.1%20perf%20%2B%20FlameGraph.md

—prof

如果开了子进程,会生成 isolate-*-v8-*.log 的子进程 log,和一个主进程 log isolate-*-v8.log
对生成的日志文件v8.log 可以用 https://github.com/mapbox/flamebearer 生成火焰图

v8-profiler

https://github.com/node-inspector/v8-profiler

Bash
profiler.startProfiling('CPU profile');
profiler.export()
  .pipe(fs.createWriteStream('cpuprofile.cpuprofile'))
  .on('finish', function() {
    profiler.delete();
  });

配合 ab-test

Bash
ab -t 300 -c 10 -p "http://localhost:8080/auth?username=matt&password=password"

把拿到的 cpuProfile 文件用 chrome js profile 打开
也可以用 speedscope  打开 cpuProfile 文件