背景
服务器用的Openresty,代码用Lua+Php编写
处理
登录到机器,发现nginx一个worker进程出现了cpu 100%的情况:
使用pstack 多次查看该worker进程,也都是同样结果。
看来是代码出现了热循环,接下来要做的就是定位到热循环 的地方。
该接口除了使用lua外,还有c的扩展。
所以想着使用采样工具并生成火焰图来定位问题。这里使用春哥提供的 openresty-systemtap-toolkit 工具进行采样。(话说安装systemtap的过程遇到了点小麻烦,主要问题是linux内核版本被公司编译时修改了。具体安装可参考build-systemtap)
使用c级别采样工具:
1
./sample-bt -p 16985 -u -t 10 > c.bt
然后使用FlameGraph生成火焰图
1
2
stackcollapse-stap.pl c.bt > c.cbt
flamegraph.pl c.cbt > c.svg
最终火焰图为:
可以看出并非c扩展代码导致,还是lua代码的问题。继续lua级别采样:
1
./ngx-lua-bt --luajit20 -p 16985 > lua.bt
但是发现直接卡住,若干分钟后仍没有动静。
火焰图直观定位是没法用了,只能使用gdb来调试了。
这里仍然使用春哥提供的openresty-gdb-utils工具。
安装参见openresty-gdb-utils#installation。
在/home/root/目录下建立.gdbinit,写入
1
2
3
4
5
6
7
8
9
10
directory /path/openresty-gdb-utils-master
py import sys
py sys.path.append("/path/openresty-gdb-utils-master")
source luajit20.gdb
source ngx-lua.gdb
source luajit21.py
source ngx-raw-req.py
set python print-stack full
接下来就可以愉快的使用gdb来定位问题了。
总结:
- lua程序,大多数问题是lua代码导致的。
- 基本上采样很难奏效,此时可直接使用gdb调试
- 在可能存在性能瓶颈的地方,要做好压测。