前段时间,公司监控群内报警,某个nodeJs项目 CPU 被打满,运维大哥快速重启解决,由于现场没有保留没定位到具体问题。2周后同样的报警又出来了,只能再次祭出重启大法,按照预期果然好了。但是这问题得解啊,总不能让运维老哥哥们写个脚本每两周就重启一次吧。
在定位问题时,发现了有个叫火焰图的工具可以帮助快速准确的定位问题,简直神器,不至于猜来猜去。但是在查找相关资料的时候,发现google到的信息基本都是6、7年前的文章。难道火焰图已经过时了吗,现在已经有更好的方式来定位问题了吗?带着这些疑问决定从根源了解下火焰图的由来。
火焰图本身并不复杂。但是结合 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收集工具。
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 作者应该已经弃坑,可以使用 hyj1991 的 v8-profiler-next,支持 Node v4.x ~ v10.x版本。
7、2017年底,阿里云发布了alinode这个性能分析利器,我们有幸成为第一批使用者,为之后的几次重大活动提功力强有力的保障。
使用alinode可以很方便的一键抓取线上 cpu profile 并进行性能分析。
8、 2018年8月,诞生了一个好用的火焰图分析工具 SpeedScope ,支持3种分析模式,下面有对这个工具详细介绍。