快速定位NodeJs线上问题 - 之火焰图篇

栏目: Node.js · 发布时间: 6年前

内容简介:前段时间,公司监控群内报警,某个nodeJs项目 CPU 被打满,运维大哥快速重启解决,由于现场没有保留没定位到具体问题。2周后同样的报警又出来了,只能再次祭出重启大法,按照预期果然好了。但是这问题得解啊,总不能让运维老哥哥们写个脚本每两周就重启一次吧。在定位问题时,发现了有个叫火焰图的工具可以帮助快速准确的定位问题,简直神器,不至于猜来猜去。但是在查找相关资料的时候,发现google到的信息基本都是6、7年前的文章。难道火焰图已经过时了吗,现在已经有更好的方式来定位问题了吗?带着这些疑问决定从根源了解下火

前段时间,公司监控群内报警,某个nodeJs项目 CPU 被打满,运维大哥快速重启解决,由于现场没有保留没定位到具体问题。2周后同样的报警又出来了,只能再次祭出重启大法,按照预期果然好了。但是这问题得解啊,总不能让运维老哥哥们写个脚本每两周就重启一次吧。

在定位问题时,发现了有个叫火焰图的 工具 可以帮助快速准确的定位问题,简直神器,不至于猜来猜去。但是在查找相关资料的时候,发现google到的信息基本都是6、7年前的文章。难道火焰图已经过时了吗,现在已经有更好的方式来定位问题了吗?带着这些疑问决定从根源了解下火焰图的由来。

0x02 火焰图在nodeJs中的发展历程

火焰图本身并不复杂。但是结合 Node.js 的发展历程,每个阶段生成火焰图的形式都有所不同,把我能搜集到的方式列出来,可以根据自己的实际情况进行选择。

1、Brendan Gregg 大神发明了火焰图,并在 2011年12月正式对外发布。

2、 David Pacheco 紧接着在 2012年1月 用DTrace来抓取node项目的profile并使用火焰图来分析性能。 你的Node项目最耗时地方在哪里?(where-does-your-node-program-spend-its-time)

同期 David Pacheco 又在npm上发布了一个可以统计火焰图的package,有兴趣可以看下他的源码实现,代码不多。stackvis - npm

3、2013年的时候,Google发布了 Google Chrome’s performance analysis tool,就是我们常用的chrome浏览器中的profile收集工具。

快速定位NodeJs线上问题 - 之火焰图篇

4、2013年12月, V8添加了对 perf_events 的支持,允许使用 --perf-basic-prof 参数。支持版本为v0.11.13。使用方法如下:

# *~/node-v0.11.13-linux-x64/bin/node --perf-basic-prof hello.js &*
[1] 31441
# *ls -l /tmp/perf-31441.map*
-rw-r--r-- 1 root root 81920 Sep 17 20:41 /tmp/perf-31441.map
# *tail /tmp/perf-31441.map*
14cec4db98a0 f Stub:BinaryOpICWithAllocationSiteStub(ADD_CreateAllocationMementos:String*Generic->String)
14cec4db9920 f Stub:BinaryOpICWithAllocationSiteStub(ADD_CreateAllocationMementos:String*String->String)
14cec4db99a0 f Stub:BinaryOpICWithAllocationSiteStub(ADD_CreateAllocationMementos:String*Smi->String)
14cec4db9a20 22c LazyCompile:~nextTick node.js:389
14cec4db9cc0 156 Stub:KeyedLoadElementStub
14cec4db9e80 22 KeyedLoadIC:
14cec4db9f20 22 KeyedLoadIC:
14cec4db9fc0 56 Stub:DoubleToIStub
14cec4dba080 10c Stub:KeyedStoreElementStub
复制代码

5、2016年,Node 决定将 Chrome 浏览器的"开发者工具"作为官方的调试工具,使得 Node 脚本也可以使用图形界面调试,这大大方便了开发者。可以参考这篇文章。

$ node --inspect app.js

$ node --inspect-brk=9229 app.js
复制代码

这个方法截止目前为止应该是比较方便的抓取方式,本文后面对该方法会有一个详细的介绍。

6、 2016年,ebay 发表了一篇文章,介绍了他们使用 v8-profiler 生成 Node.js 火焰图的过程 : 点燃 Node.js 的火焰 - ebay

目前 v8-profiler 作者应该已经弃坑,可以使用 hyj1991v8-profiler-next ,支持 Node v4.x ~ v10.x版本。

7、2017年底,阿里云发布了alinode这个性能分析利器,我们有幸成为第一批使用者,为之后的几次重大活动提功力强有力的保障。

使用alinode可以很方便的一键抓取线上 cpu profile 并进行性能分析。

8、 2018年8月,诞生了一个好用的火焰图分析工具SpeedScope ,支持3种分析模式,下面有对这个工具详细介绍。

0x03 火焰图的含义

上面已经大致了解了nodeJs里面火焰图的历史。下面来说说如何看懂一张火焰图吧,下图是我们真实项目中的一次压测时抓取的数据。

快速定位NodeJs线上问题 - 之火焰图篇

火焰图基本含义:(来源: 如何读懂火焰图? - 阮一峰的网络日志

  • 每一个小块代表了一个函数在栈中的位置(即一个栈帧)。
  • y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
  • x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
  • 小块的宽度代表 CPU 的使用时间,或者说相对于父函数而言使用 CPU 的比例(基于所有样例),越宽则代表占用 CPU 的时间越长,或者使用 CPU 很频繁。 如果一个函数在顶层占据的宽度最大,就表示该函数可能存在性能问题。

0x04 案例分析

快速定位NodeJs线上问题 - 之火焰图篇

根据上一环节对火焰图的定义,结合上图的压测数据,已经标注出三个优先级最高,可能存在问题的地方:

request
transformResponse

结合实际情况,下图为该问题发生时大致的效果(因为现场图没有保存下来,下面是后来压测模拟的效果)

快速定位NodeJs线上问题 - 之火焰图篇
TIME_WAIT

根据上面分析,猜测应该是图中问题1的地方所导致的。从代码中定位到确实是我们内部framework中对axios统一封装的 fetch 方法没有处理好导致。问题2、3虽然有优化空间,但不是导致CPU飙升的根源所在。修改后压测数据终于恢复正常。

0x05 最佳实践

上面火焰图历史的部分已经介绍了很多种抓取火焰图的方法,但是很多方法上手难度较高,有的需要侵入代码进行改造。

1、收集

NodeJs v6.3.0+ 推荐使用 --inspect 来抓取,并且使用 chrome-devtools:// 来分析。

  1. 运行node时添加 --inspect 参数
node --inspect app.js
复制代码
  1. 打开chrome浏览器,直接输入 chrome://inspect ,如下图的地方选择 inspect。
快速定位NodeJs线上问题 - 之火焰图篇
  1. 点击start后就可以对node项目进行压测了。
快速定位NodeJs线上问题 - 之火焰图篇
  1. 压测成功后,保存 CPU-xx.cpuprofile cpuprofile文件到本地。

2、分析

推荐使用speedscope 来分析火焰图的趋势,打开官网,选择刚才本地保存的文件,支持在线分析也可以安装speedscope到本地。它支持三种模式:

  1. Time Order 模式:默认按照时间顺序排列;
  2. Left Heavy 模式:会把最宽的堆栈放在最左侧,依次往右排列,便于快速定位问题;
    1. Sandwich 模式:可以看到每个函数的相关的时间;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Professional JavaScript for Web Developers

Professional JavaScript for Web Developers

Nicholas C. Zakas / Wrox / 2009-1-14 / USD 49.99

This eagerly anticipated update to the breakout book on JavaScript offers you an in-depth look at the numerous advances to the techniques and technology of the JavaScript language. You'll see why Java......一起来看看 《Professional JavaScript for Web Developers》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具