NodeJS 性能优化之 CPU 看图篇

服务稳定性到一定程度之后,都会开始经历一段精细化运营的过程,从成本意识角度来说也是成立的。作为前端出身的NodeJS开发者们,产生共鸣的那就是如何能够直观且快速发现性能瓶颈,能够像调试前端的JS代码那样可视化,堆栈化,接下来我们就针对常见的CPU性能分析方法来揭开NodeJS的CPU面纱。

一、CPU使用情况可视化展示(火焰图—Flame Graph)

充分利用劳动工具有助于帮助我们提升定位问题的效率,Linux kernal自带的系统性能分析工具perf,为我们提供函数级与指令级的热点查找,常用于性能瓶颈的查找与热点代码定位。

#NodeJS如何正确完整的采集火焰图呢?

1-1、用例构造

NodeJS服务代码示例—JSON编解码,如下片段:

1-2 启动方式:

启动参数:--perf_basic_prof或—perf-basic-prof适用于node@0.11.13

也可以使用--perf_basic_prof_only_functions

标准方式:node --perf_basic_prof JsonParse.js

MIG tafNodeJS启动方式:私有模板配置启动参数,如下:


<taf>

<application>

    <server>

        node-args=--perf-basic-prof

</server>

</application>

</taf>

注:--perf_basic_prof或--perf-basic-prof会对应生成一个/tmp/perf-pid.map文件,如图:

1-3 perf脚本采集函数和热点代码

#查看NodeJS服务进程pid,采集时需要用到。命令:$ ps –ef | grep ‘worker’

#采集脚本:$ perf record -F 99 -p 182497 -g -- sleep 60

参数说明如下:

采集频率(ms)

进程pid

调用记录

记录时长

-F 99

-p 182497

-g

--sleep 60

#进程对应的符号表perf-pid.map权限设置:$chown root /tmp/perf-pid.map

踩过的坑!!!是为了消除下面这个问题的

File /tmp/perf-PID.map not owned by current user or root, ignoring it (use -f to override).

Failed to open /tmp/perf-PID.map, continuing without symbols

  • 挖出FlameGraph开源库里面的stackcollapse-perf.pl和flamegraph.pl

http://github.com/brendangregg/FlameGraph

  • svg文件生成

单一颜色:$ perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > xxx.svg

多种颜色:perf script | ./stackcollapse-perf.pl | ./flamegraph.pl --color=js –hash > xxx.svg,如下图:

二、CPU火焰图的理解与性能分析

2.1 通过上面的步骤采集出两种不同颜色系的火焰图,如下图

2.2 火焰图颜色对应关系,如下表:

颜色

类型

绿色

JS代码调用

蓝色

优化编译代码

黄色

C++/C代码

红色

libuv系统调用

2.3 火焰图形状对应关系

形状

含义

每一个平面方块

一个函数在栈中的位置(也称一个栈帧)

Y轴

栈的深度(也叫栈的帧数)

X轴

表示总的样例,不过它们左右顺序没有特殊含义

每个平面方块的宽度

方块的宽度标示CPU使用时间或者说相对父函数而言使用CPU的比率,越宽代表占用CPU的时间越长,或者使用CPU很频繁

2.4 JSON序列化与反序列化火焰图分析

采用ab进行压力测试分析JSON.parse与JSON.stringify性能开销

压测命令:ab –n 3000000 -c 50 http://ip:port/jsonParse

从火焰图看到JsonParse.js里面耗时主要消耗在JSON序列化和反序列化

几个常见的栈帧类型说明:

栈帧

含义

LazyCompile

指的是下回会被编译

Builtin

指的是C++内置的运算方法

Stub

C入口桩代码:作用是在js的JIT代码中,如果要调用Runtime的函数,则通过CEntryStub实现

V8::internal

内部命名空间,就是C++的namespace,在V8的源代码可以找到对应的namespace

2.5 JSON反序列化(JSON.parse)源码分析

概念普及——解析器常见原理:

a) 词法分析

b) 语法分析生成抽象语法树(AST)

c) 针对抽象语法树进行语义分析,构建你需要的内部数据结构或生成代码

通过局部查看火焰图分析源码

1 Stub:CEntryStub:C入口桩代码,在JS的JIT代码中,提供调用Runtime的函数(如DOM函数或者JS的builtin函数)

2【编译builtins.h】v8::internal::Builtin_JsonParse

3【解析器json-parser.cc】v8::internal::JsonParser<true>::ParseJson

4【词法分析json-parser.cc】v8::internal::JsonParser<true>::ParseJsonValue

5【语法分析json-parser.cc】v8::internal::JsonParser<true>::ParseJsonObject

小结:通过火焰图我们能够清晰的看到函数的调用栈,并能够找到哪些函数是耗时较多的

JSON序列化流程相似相似,感兴趣的同学可以看一下V8的json-stringifier.cc和对应的.h文件

三、CPU性能分析的另一种可视化dot图

3.1 需要gprof2dot脚本

工程地址:https://github.com/jrfonseca/gprof2dot.git

3.2 基于perf.data文件转换成dot文件

$ perf script -i perf.data.pid | python gprof2dot.py –f perf –e 1 –o xxx.dot

3.3 基于perf.data文件转换成dot文件

$ dot –Tsvg xxx.dot –o xxx.svg

在linux物理机的尝试:

下载到PC磁盘,打开即可:

附录

https://zhuanlan.zhihu.com/p/27147421

https://www.zhihu.com/question/24640264

http://blog.12.rs/notes/V8-0.2.5-JIT/

https://github.com/zfengzhen/Blog/blob/master/article/hold%E4%BD%8F%E4%BD%A0%E7%9A%84%E5%90%8E%E5%8F%B0%E7%A8%8B%E5%BA%8F.md

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

郑清江的专栏

1 篇文章1 人订阅

我来说两句

3 条评论
登录 后参与评论

相关文章

来自专栏瓜大三哥

HLS Lesson16-数组优化:数组分割

数组可以通过resource这个directive精确指定当前使用的memory。比如是分布式RAM还是Block RAM,采用单端口或者双端口。提高数据的吞吐...

23310
来自专栏机器之心

处理器高危漏洞无人幸免?树莓派:我们不受影响

2365
来自专栏决胜机器学习

数据库专题(三) ——Mysql ID生成器

数据库专题(三)——Mysql ID生成器 (原创内容,转载请注明来源,谢谢) 注:本文是我对ID生成器的见解,如果有偏差欢迎指正。 一、需求 在数据库中,...

3008
来自专栏张善友的专栏

利用 Microsoft StreamInsight 控制较大数据流

原文地址:http://msdn.microsoft.com/zh-cn/magazine/hh205648.aspx 下载代码示例 生产线的产量下降后,将...

1756
来自专栏文渊之博

PowerBI 引入时间智能

简介 Power BI Desktop -是一款由微软发布的自助式商业智能工具,功能强大、易于使用。其中还可以通过微软云连多个数据源并且使用数据源来创建可视化表...

2409
来自专栏深度学习之tensorflow实战篇

计算机常用算法对照表整理

常用对照: NLP CRF算法: 中文名称条件随机场算法,外文名称conditional random field algorithm,是一种数学算法,是2...

3535
来自专栏数值分析与有限元编程

ANSYS模拟梁单元铰接点

ANSYS模拟梁单元铰接点有以下几种方法: 1.BEAM3/BEAM4单元,利用结点自由度耦合来实现铰接,在铰接处设两个单独的结点,每个结点只与一个梁单元连接,...

2885
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(三):基本模块调用(格式、计数、概要统计、排序等)(上)

搞定基本的函数之后,开始鼓捣SAS里面的模型。也就是说,要开始写PROC了。说实话,越学SAS,越觉得SAS像Stata...无论是从输出 的样式,还是语法。好...

3395
来自专栏技术博文

php性能监测模块XHProf

一,什么是XHProf XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可...

3486
来自专栏点滴积累

geotrellis使用(三)geotrellis数据处理过程分析

之前简单介绍了geotrellis的工作过程以及一个简单的demo,最近在此demo的基础上实现了SRTM DEM数据的实时分析以及高程实时处理,下面我就以我实...

3916

扫码关注云+社区