# 性能工具:Node.js性能分析工具

  • Node.js 自带 profile
  • Chrome devtool:使用--inspect,或者--inspect-brk开启调试开关,如node --inspect path/xxx.js 或者node --inspect-brk path/xxx.js。通过浏览器控制面板可以获取内存使用情况,CPU计算性能。NodeJS程序调用堆栈等信息。
  • clinicNearForm提供的开源Node.js性能分析套件
  • easy-monitor:企业级 Node.js 应用性能监控与线上故障定位解决方案
  • AliNode:基于 Node 运行时的应用性能管理解决方案

# Node 自带 profile

  • 第1步: 以--prof参数启动Node应用

    $ node --prof index.js
    
  • 第2步: 通过压测工具ab向服务施压

    ab -t 15 -c 100 `127.0.0.1/test`
    
  • 第3步: 处理生成的log文件

    $ node --prof-process isolate-0XXXXXXXXXXX-v8-XXXX.log > profile.txt
    
  • 第4步: 分析profile.txt文件

    profile.txt 文件如下图,包括JS和C++代码各消耗多少ticks, 具体分析方法详见node profile文档

在您最喜欢的文本编辑器中打开 processed.txt 将给您提供一些不同类型的信息。首先,我们看一下摘要部分:

 [Summary]:
   ticks  total  nonlib   name
     79    0.2%    0.2%  JavaScript
  36703   97.2%   99.2%  C++
      7    0.0%    0.0%  GC
    767    2.0%          Shared libraries
    215    0.6%          Unaccounted

这告诉我们:收集到的所有样本中有 97% 是在 C++ 代码中进行的。当查看处理的输出的其它部分时,我们应该最注意 C++ 中所做的工作(而不是 JavaScript)。考虑到这一点,我们接下来会找到 [C++] 部分,其中包含有关 C++ 函数占用最多 CPU 时间的信息,然后查看一下:

 [C++]:
   ticks  total  nonlib   name
  19557   51.8%   52.9%  node::crypto::PBKDF2(v8::FunctionCallbackInfo<v8::Value> const&)
   4510   11.9%   12.2%  _sha1_block_data_order
   3165    8.4%    8.6%  _malloc_zone_malloc

我们看到,前 3 个条目占了程序占用的 CPU 时间的 72.1%。从这个输出中,我们立即看到至少 51.8% 的 CPU 时间被称为 PBKDF2 的函数占用。它与用户密码中的哈希生成相对应。为了更好地理解这些函数之间的关系,接下来我们将查看[自下而上(重)配置文件]部分,该节提供有关每个函数的主要调用方的信息。检查此部分,我们会发现:

   ticks parent  name
  19557   51.8%  node::crypto::PBKDF2(v8::FunctionCallbackInfo<v8::Value> const&)
  19557  100.0%    v8::internal::Builtins::~Builtins()
  19557  100.0%      LazyCompile: ~pbkdf2 crypto.js:557:16

   4510   11.9%  _sha1_block_data_order
   4510  100.0%    LazyCompile: *pbkdf2 crypto.js:557:16
   4510  100.0%      LazyCompile: *exports.pbkdf2Sync crypto.js:552:30

   3165    8.4%  _malloc_zone_malloc
   3161   99.9%    LazyCompile: *pbkdf2 crypto.js:557:16
   3161  100.0%      LazyCompile: *exports.pbkdf2Sync crypto.js:552:30

在上面的每个“调用堆栈”中,父列中的百分比告诉您当前行中的函数调用了上一行中的函数所采样的百分比。例如,在上面针对_sha1_block_data_order 的中间“调用堆栈”中,我们看到 _sha1_block_data_order 出现在11.9%的样本中,这可以从上面的原始计数中得知。但是,在这里,我们还可以说它总是由Node.js加密模块中的 pbkdf2 函数调用。我们看到类似地,_malloc_zone_malloc 几乎完全由同一pbkdf2 函数调用。

在这一点上,很明显:基于密码的哈希生成应该是我们优化的目标。谢天谢地,您已经完全了解了异步编程的好处,并且您认识到从用户密码生成哈希的工作正在以同步方式进行,从而绑定了事件循环。这将阻止我们在计算哈希时处理其它传入请求。

# 总结

总的来说,首先找到调用耗时的地方。然后,通过调用堆栈,找到来源,对耗时的函数进行优化。

更新时间: 6/29/2020, 6:30:01 PM