Open jinhailang opened 6 years ago
火焰图可以用来分析程序代码函数层的 CPU 或内存的使用情况,为程序的优化提供很直观的参考。 因此,对一个成熟的项目来说,能够随时收集运行时的火焰图必不可少。
得益于春哥对动态追踪技术的研究(动态追踪技术漫谈,建议先看一下),OpenResty 提供了很多调试工具,其中就包括火焰图收集脚本。
下载 OpenResty 项目源码,编译(configure)带上 --with-debug,开启调试模式编译;
configure
--with-debug
安装 systemtap,以及内核调试信息,注意要跟内核版本保持一致:
uname -r #查看内核版本 apt-get install systemtap linux-image-`uname -r`-dbg linux-headers-`uname -r` #自动安装
下载调试工具 stapxx
git clone https://github.com/openresty/stapxx.git cd ./stapxx export PATH=$PWD:$PATH
收集 CPU
./samples/lj-lua-stacks.sxx --skip-badvars -x PID > a.bt #PID 即 nginx worker 进程 id ./fix-lua-bt a.bt > a.bt #美化数据,去除杂音 https://github.com/openresty/openresty-systemtap-toolkit#fix-lua-bt
收集内存
./samples/sample-bt-leaks.sxx -x PID -v > a.bt #PID 即 nginx worker 进程 id
下载 FlameGraph 将堆栈信息生成火焰图
tar -zxf FlameGraph.tar.gz cd ./FlameGraph ./stackcollapse-stap.pl ../stapxx/a.bt > a.cbt ./flamegraph.pl --encoding="ISO-8859-1" --title="Lua-land on-CPU flamegraph" a.cbt > a.svg
使用浏览器打开 a.svg 即可得到火焰图
a.svg
CPU 火焰图实例:
内存火焰图实例:
抓不到 LuaJit 采样数据的情况:WARNING: Found 0 JITted samples. 可能是因为请求数太少了,见春哥回答:
WARNING: Found 0 JITted samples.
这两个工具都被设计成分析非常繁忙的 nginx worker 进程(CPU 使用率接近 100%,每秒处理几百、几千、乃至几万个请求)时仍然开销极小(吞吐量极限的损失低于 5%),所以你只应当你的目标 worker 进程的 CPU 使用率足够高时(至少超过 10% 吧),才能得到比较有意义的结果。它们是通过 OS 内核 tick 或者 cpu clock 探针按 CPU 时间进行分时采样的,而并不是追踪每一个具体的请求(此种做法开销很大)。
程序中引用了 lua cjson 包,使用 stapxx 工具抓取时可能会出现链接或函数找不到之类的错误。此时,需要重新编译 cjson:
lua cjson
stapxx
cjson
git clone https://github.com/openresty/lua-cjson.git cd lua-cjson/
LUA_VERSION = 5.1 TARGET = cjson.so PREFIX = /usr/local/openresty/luajit CFLAGS = -g -Wall -pedantic -fno-inline CFLAGS = -O3 -Wall -pedantic -DNDEBUG CJSON_CFLAGS = -fpic CJSON_LDFLAGS = -shared LUA_INCLUDE_DIR ?= $(PREFIX)/include/luajit-2.1 LUA_CMODULE_DIR ?= /usr/local/openresty/lualib LUA_MODULE_DIR ?= $(PREFIX)/share/lua/$(LUA_VERSION) LUA_BIN_DIR ?= $(PREFIX)/bin
注意看错误信息,出现连接符或未知函数变量之类的错误一般都是对应的组件没有调试信息,重新编译对应的组件,编译时开启调试模式即可。
火焰图可以用来分析程序代码函数层的 CPU 或内存的使用情况,为程序的优化提供很直观的参考。 因此,对一个成熟的项目来说,能够随时收集运行时的火焰图必不可少。
得益于春哥对动态追踪技术的研究(动态追踪技术漫谈,建议先看一下),OpenResty 提供了很多调试工具,其中就包括火焰图收集脚本。
火焰图收集流程
下载 OpenResty 项目源码,编译(
configure
)带上--with-debug
,开启调试模式编译;安装 systemtap,以及内核调试信息,注意要跟内核版本保持一致:
下载调试工具 stapxx
收集 CPU
收集内存
下载 FlameGraph 将堆栈信息生成火焰图
使用浏览器打开
a.svg
即可得到火焰图CPU 火焰图实例:
内存火焰图实例:
踩过的坑
抓不到 LuaJit 采样数据的情况:
WARNING: Found 0 JITted samples.
可能是因为请求数太少了,见春哥回答:程序中引用了
lua cjson
包,使用stapxx
工具抓取时可能会出现链接或函数找不到之类的错误。此时,需要重新编译cjson
:git clone https://github.com/openresty/lua-cjson.git cd lua-cjson/
Build defaults
注意看错误信息,出现连接符或未知函数变量之类的错误一般都是对应的组件没有调试信息,重新编译对应的组件,编译时开启调试模式即可。