一 环境准备
1. systemtap 安装
1 2 3
| $yum install systemtap $yum install kernel-devel $sudo stap -ve 'probe begin { log("hello world") exit() }'
|
2. 安装 debug 包
通过 uname -r
查看系统版本,到网站 http://debuginfo.centos.org/
下载相应的软件包进行安装。
1 2 3 4 5
| $wget http://debuginfo.centos.org/6/x86_64/kernel-debug-debuginfo-2.6.32-696.20.1.el6.x86_64.rpm $wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-2.6.32-696.20.1.el6.x86_64.rpm $wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-common-x86_64-2.6.32-696.20.1.el6.x86_64.rpm $rpm -Uhv kernel-debuginfo-*.rpm $rpm -Uhv kernel-debug-*.rpm
|
使用 yum 安装更方便
1 2 3
| yum search kernel-debug yum install -y kernel-debuginfo-common-x86_64.x86_64 kernel-debug.x86_64 kernel-debug-devel.x86_64 kernel-debuginfo.x86_64 debuginfo-install -y kernel-3.10.0-693.el7.x86_64
|
执行命令测试
1 2 3 4
| [root@localhost ~] kernel.function("printk@kernel/printk.c:641") $fmt:char const* $args:va_list $r:int [root@localhost ~] process("/lib64/libc-2.12.so").function("malloc")
|
3. 下载火焰图生成工具
1 2
| git clone https://github.com/brendangregg/FlameGraph.git git clone https://github.com/openresty/openresty-systemtap-toolkit.git
|
二 NGINX 程序分析
1. NGINX 程序安装
使用 systemtap
分析 NGINX 非常方便, 正常编译安装进行测试并采集调用栈数据即可.
1 2 3 4 5
| $sudo yum install gcc gcc-c++ $cd /opt/nginx-1.12.1 $./configure --with-http_dav_module --with-http_stub_status_module --add-module=/opt/nginx-1.12.1/src/dynamod/nginx_accept_language_module $make $make install
|
2. 采集 NGINX 数据
1 2 3 4
| $cd /usr/local/nginx/sbin $sudo ./nginx $ps -ef|grep nginx $sudo stap --ldd -d /usr/local/nginx/module/ngx_http_du_entry_module.so -d /usr/local/nginx/sbin/nginx --all-modules -D MAXMAPENTRIES=10240 -D MAXACTION=20000 -D MAXSTRINGLEN=4096 -D MAXBACKTRACE=10240 -x 18421 ngx.stp --vp 0001 > ats.out
|
stap 参数:
x : 分析进程 pid
ldd : 指定分析的执行程序、动态模块
MAXACTION : 单个探针命中执行的最大次数
MAXSTRINGLEN : 字符串最大长度
MAXBACKTRACE : 栈展开的最大深度
3. 生成 NGINX 运行火焰图
1 2 3 4 5
| # 下载火焰图项目代码 $git clone https://github.com/brendangregg/FlameGraph.git # 使用 FlameGraph 项目脚本生成火焰图 $perl stackcollapse-stap.pl ats.out > ats.out2 $perl flamegraph.pl ats.out2 > ats.svg
|
将生成的 ats.svg 文件在浏览器打开就可以看到火焰图。
三 OpenResty 程序分析
如果不需要分析 lua 调用栈, 可以使用分析 NGINX 方法生成火焰图. 如果需要分析 lua 调用栈, 需要使用 OpenResty 社区的分析工具进行分析.
1. lj-lua-stacks 下载
1
| git clone https://github.com/openresty/stapxx
|
2. OpenResty 编译
目前火焰图工具不支持 GC64 需要使用 --without-luajit-gc64
关闭 GC64 选项. 同时需要区分 OpenResty 版本是否默认启用 luajit, 可以使用 --with-luajit
开启.
1 2 3 4 5
| $./configure --prefix=/usr/local \ --with-debug --with-pcre-jit --with-ipv6 \ --without-luajit-gc64 --with-luajit
$make && make install
|
3. 采集数据
1 2 3 4 5 6
| $lj-lua-stacks.sxx -I ./stapxx/tapset -D MAXMAPENTRIES=102400 --arg time=10 --skip-badvars -x 1398924 > a.bt
$git clone https://github.com/brendangregg/FlameGraph.git
$stackcollapse-stap.pl a.bt > a.cbt $flamegraph.pl --encoding="ISO-8859-1" --title="Lua-land on-CPU flamegraph" a.cbt > a.svg
|
lj-lua-stacks
参数:
-I ./stapxx/tapset
指定 stap++
依赖库目录.
-D MAXMAPENTRIES=102400
指定 stap 使用 map 的最大记录数.
--arg time=10
采集时间, 单位秒.
-x 1398924
Nginx Worker 进程号.
四 火焰图含义
- y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
- x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。
五 参考资料