一、debug_pool内存排查利器
1)接口调用观察,使用方法
$ curl xxx://localhost:80/debug_pool
pid:18821
size: 223784 num: 2 cnum: 1 lnum: 10 ngx_init_cycle
size: 1536 num: 4 cnum: 1 lnum: 10 ngx_event_accept
size: 0 num: 1 cnum: 0 lnum: 0 ngx_http_lua_create_fake_request
size: 0 num: 1 cnum: 0 lnum: 0 main
size: 0 num: 1 cnum: 0 lnum: 0 ngx_http_lua_create_fake_connection
size: 0 num: 1 cnum: 0 lnum: 6 ngx_http_server_names
size: 8192 num: 4 cnum: 1 lnum: 0 ngx_http_create_request
size: 0 num: 1 cnum: 0 lnum: 0 ngx_http_lua_init_worker
size: 228KB num: 15 cnum: 3 lnum: 26 [SUMMARY]
2)指定pid观察
你可以使用gdb脚本debug_pool.gdb来获取指定进程的内存使用情况。
某些进程无法处理HTTP请求,列如master进程和tengine Proc 进程。
下面的示例展示如何获取master进程的内存使用情况。
$ gdb -q -x debug_pool.gdb -p <pid of master process> |
3)参数说明
除了最后一行的每一行的输出内容都有相同的格式,如下:
"__size__: %12u __num__: %12u __cnum__: %12u __lnum__: %12u __\<function name\>__"
- size: 当前内存池占用的内存
- num: 内存池创建的个数(包括当前正在使用的内存池数量和已经被释放的内存池数量)
- cnum: 当前正在使用的内存池数量
- lnum: 该类内存池调用ngx_palloc_large()次数
- funcion name: 创建该内存池的nginx/tengine C函数的函数名
- 通过创建该内存池的函数的函数名,我们可以知道各个模块的内存使用情况,列如:
ngx_http_create_request
创建的内存池用于HTTP请求。- 因为大多数模块直接从该内存池上分配内存,所以很难区分具体哪个模块使用了内存。
ngx_event_accept
创建的内存池用于TCP连接。ngx_init_cycle
创建的内存池用于解析nginx/tengine的配置和保存其他全局数据结构。ngx_http_lua_init_worker
用于指令init_worker_by_lua。- ...
最后一行的输出内容汇总了所有内存池的信息。
二、asan扫描
1.安装asan库
RUN yum install devtoolset-7-libasan-devel -y
2.支持asan编译
RUN cd /root/nginx-rtsp/openresty-1.19.3.2 && ASAN_OPTIONS=detect_leaks=0 ./configure --prefix=/opt/nginx \
--with-pcre-jit \
--with-http_ssl_module \
--with-http_v2_module \
--add-module=../ngx_rtsp_module \
--add-module=../ngx_ff_module \
--add-module=../nginx-toolkit-module \
--add-module=../nginx-client-module \
--add-module=../nginx_upstream_check_module \
--add-module=../ngx_http_upstream_dyups_module \
--add-module=../3rdparty/ngx_debug_pool \
--with-cc-opt="-Werror -W -g -O0 -fno-omit-frame-pointer -fsanitize=address -fsanitize-recover=address" \
--with-ld-opt="-fsanitize=address -fsanitize-recover=address -lpthread"
3.环境变量配置
ENV ASAN_OPTIONS=halt_on_error=0:detect_container_overflow=0
4.扫描结果查看
过滤error.log日志AddressSanitizer字段排查异常。
三、perf & FlameGraph火焰图分析
1)下载地址:官方下载FlameGraph即可。
2)使用说明:
perf record -e cpu-clock -g -p 1451612 //-p指定pid值,生成perf.data
perf script -i perf.data > perf.script //解析
./FlameGraph-master/stackcollapse-perf.pl perf.script >pref.folded //符号折叠
./FlameGraph-master/flamegraph.pl pref.folded >perf.svg //火焰图生成