因为一直在ubuntu上使用,所以安装很简单 sudo apt-get installsystemtap,源码安装的话请参考这篇文章: http://www.cnblogs.com/hazir/p/systemtap_introduction.html中的方法一。
二、内核调试信息
不用跟踪内核态性能大概也不需要,不过保不齐会用到所以我也把内核调试信息搞上了。对于ubuntu这种发行版内核来说好处是官方已经提供了(URL: http://ddebs.ubuntu.com/pool/main/l/linux/),根据自己的内核(uname-a 查询)挑选版本。 如我的是Linux ubuntu 3.13.0-32-generic那么对应的就是:linux-image-3.13.0-32-generic-dbgsym_3.13.0-32.57_amd64.ddeb。
下载后用 dpkg -ilinux-image-3.13.0-32-generic-dbgsym_3.13.0-32.57_amd64.ddeb安装。
三、Hello Systemtap!
上面这些完成以后可以使用命令:sudo stap -ve 'probe begin { log("hello Systemtap!")exit() }' 来测试是否安装成功。如果成功的话会有类似下面的输出:
四、nginx-systemtap-toolkit
进入正题,这个就是主要介绍的章亦春大神写的systemtap nginx调试的系列脚本了(URL: Github地址),提供了活动请求的查询、ngx_lua模块的当前lua堆栈查看、pcre模式串/运行时间分析、C堆栈采样等等炸裂功能。
首先介绍下C堆栈采样这个脚本,结合Brendan Gregg大神写的FlameGraph tools(URL: https://github.com/brendangregg/FlameGraph),可以画出功能实用、看着酷炫的火焰图。如图:
这个东西的原理就是在程序运行的时候每隔一定的时间对指定进程的C堆栈进行采样,将当前各栈帧的函数名保存起来。因为采样时间是恒定的,所以最后的结果上如果一个函数占用cpu时间越长,那么得到的采样次数也就越多,最后反映到火焰图上的横轴长度就越长。另外颜色深浅其实没什么含义,只是方便查看。
使用方法:
1、首先确定编译的代码要带有调试i信息,以便调试脚本可以获得具体的代码信息。如nginx就要加上--with-debug开关。
2、其次要调优的进程已经启动,并且获得其pid,对于nginx这种多进程的程序,需要找到一个worker进程的pid,所以如果是开发环境调优的话,可以考虑使用单进程跑nginx。
3、命令sudo ./nginx-systemtap-toolkit/sample-bt -p 1147 -u -t 20 >trace.txt
其中-p 指定进程的pid
-u 追踪用户态的调用堆栈(也可以使用-k追踪程序运行期间在内核态的堆栈)
-t 脚本的运行时间,达到时间之后脚本自动停止,将堆栈信息输出,单位为秒
启动后会有类似的信息:
WARNING: Tracing 1147 (/home/kawaru/nginx/sbin/nginx) in user-spaceonly...
提示已经开始跟踪,这是可以用ab等等东西打点流量,等20秒之后会显示:
WARNING: Time's up. Quitting now...(it may take a while)
这时候有可能需要多等一会,成功完成后会在trace.txt里看到类似
一堆堆栈信息。
4、制作火焰图,这时就需要用到flame graph tools了,一共分为两步:
一个是根据不同工具生成的堆栈信息转化为一个调用计数结果,因为我们用的是systemtap生成的,所以使用stackcollapse-stap.pl这个脚本,命令如下:
./FlameGraph/stackcollapse-stap.pl ./trace.txt > trace.out
之后再使用flamegraph.pl生成最终的svg格式的火焰图,命令:
./FlameGraph/flamegraph.pl ./trace.out > trace.svg
最后就可以看到浏览器里打开trace.svg,看到酷炫的火焰图了:
上面介绍的是sample-bt这个脚本,比较适用于cpu占用较高时对低效代码的排查,如果cpu占用不高,但运行的效率还是很低可以考虑是否是阻塞在io上,这时可以使用sample-bt-off-cpu这个脚本,查看io阻塞在哪段代码上,以便着手优化,使用方法差不多就不单独介绍了。
另外一个比较实用的是ngx-pcre-stats 这个,可以追踪nginx运行过程中跑pcre正则的性能,具体使用:
sudo ./ngx-pcre-stats -p 11276 --total-time-top --luajit20
-p 进程pid
--luajit20 根据系统里用的是lua5.1还是luajit2.0分别使用--lua51或者--luajit20
--total-time-top 追踪时的针对的项目,一共有四个除了total-time-top这个追踪单个正则总计运行时间外,还有--exec-time-dist:查看正则运行时间分布,--worst-time-top,运行时间最差情况的十条正则;--data-len-dist正则匹配时匹配串的长度分布。这四个项目每次运行时候选择一个使用。
-t 跟踪时间,单位为秒,不指定的话ctrl-c结束。
使用效果:
可以看出最差情况下第一条运行时间消耗比较多,这时就可以考虑使用常用的正则优化手段进行优化,比如使用非贪婪模式,减少不必要的不定长量词的使用等等。
其他几个脚本用处也很大,可以参考春哥的那个github页面上的介绍。除了nginx-systemtap-toolkit外,春哥还有个stap++,是对systemtap的一个简单扩展,功能也很多可以自行研究。
参考资料:
systemtap安装: http://www.cnblogs.com/hazir/p/systemtap_introduction.html
nginx-systemtap-toolkit: https://github.com/openresty/nginx-systemtap-toolkit
stap++: https://github.com/openresty/stapxx
FlamgGraph tools: https://github.com/brendangregg/FlameGraph