序言
虽然nginx+lua开发一些小的web服务简单快捷,但是由于种种原因,配套的工具比较缺乏,监控工具和性能检测工具等等。而且lua作为一种跑在虚拟机的脚本语言,虽然做的短小精悍,但是。。。功能和可调优的空间还是欠缺了点。
前段时间使用春哥的systemtap脚本对我的lua服务做了下性能测试,这里记录一下折腾的历程
准备
systemtap是一个性能检测和调试跟踪的工具,最开始是为了调试内核被做出来的,后来添加了用户态跟踪的功能。
折腾记录
春哥的脚本要求systemtap2.2以上,公司测试服务器自带的systemtap脚本的版本那是1.6,远远不够,所以必须手动编译一个。下载systamtap的源码,然后./configuare + make就可以直接编了。最开始碰到的问题是公司el5系统的服务器的elfutil版本太低,得自己编译一个高版本的elfutil然后指定路径。。。。我怕麻烦,就把一个空的测试机器重装成el6,elfutil的版本立马就够了(我真是太机智了)。
顺利编译出systamtap之后(中途遇到了systemtap版本不够新导致的符号找不到的bug),就是tengine的安装,时间都折腾在这上面了。。。我们项目用的是tengine-ads这个版本,直接用tengine缺少模块,就请了tengine组的同学帮忙把模块给打了进去。由于要跟踪lua内部,所以自带的luajit必须-g编译。那边的同学比较忙,我就只能自己要了服务器权限跑上去自己编,编了几次之后那个测试服务器竟然磁盘满了。。。总之就是折腾了一晚上和一早上,终于把带debuginfo的tengine给装上了。
效果
启动tengine服务,把压测程序开好,运行
./ngx-sample-lua-bt -p 29237 --luajit20 -t 200 -a '--vp 02 -R /home/wenqian.peiwq/systemtap-2.6/runtime -DSTP_NO_OVERLOAD --all-modules -DMAXSKIPPED=1024 ' > tmp.bt
采样结束后,利用brendangregg的FlameGraph tools可以绘制栈调用的火焰图,如下:
通过这个图,先是立马发现了一个低级错误。。。(上面贴的图上已经没了),我有很多打印debug的语句,用了这类用法
_log.log("debug", "xxx", util.print_r(some_data))
忘记了lua的求值策略,虽然debug下的这个语句在生产环境中不执行,但是由于求值策略,util.print_r(some_data)
仍然会先求值,导致了很大的性能损失,接近1/4。
同时也发现了UUID的生成所占用的时间也过分的长了一些,然后重写了这个方法,使用了resty.string库中的random模块(直接调用了ngx_*的C函数),然后利用systemtap对比了前后的时间,提升了360%多,可见还是很有效果的。
注:
这个项目是基于我上次手撸的小框架dodolu,根据这次的测试结果,框架的封装对我的项目造成的性能损失在1%以下。
posted on 2015-01-09 12:03
右席 阅读(2326)
评论(0) 编辑 收藏 引用