Debugging NGINX

这篇文章来自nginx document  https://docs.nginx.com/nginx/admin-guide/monitoring/debugging/

nginx的故障排除和大多数程序一样, 可以通过gdb调试二进制文件, 增加debug日志,或者分析coredump文件方式解决。

配置nginx

nginx 商业版本从Release8开始已经提供nginx-debug版本,使用这个版本直接在配置文件中将日志设置成debug级别即可。

error_log  /var/log/nginx/error.log debug;

如果是开源版本, 需要增加–with-debug标识重新编译, 步骤如下

$nginx -V 2>&1 | grep  arguments
$./congfigure --with-debug <other configure arguments>
$sudo make
$sudo make install
 调试符号

和大多数调试都需要增加调试符号,他可以提供除了内存地址以外的其他信息, 将可执行文件中的内存地址和如变量名称, 函数,类,数据结构,源码行数这些代码中的信息关联起来。

编译通过增加-g可以包含调试符号。

$ ./configure --with-debug --with-cc-opt='-O0 -g'

Debug日志

当二进制支持debug日志后,还需要在配置文件中配置日志路径。日志可以存放到内存中, 标准输出中,或者指定的文件中。默认配置可以看到通过error_log变量指定到文件中。

$ cat /etc/nginx/nginx.conf
$ error_log /var/log/nginx/error.log debug;
内存方式

配置

error_log memory:32m debug;

调试

$sudo gdb -p <pid>

将调试脚本拷贝到gdb中,按回车日志就会输出到 debug_log.txt文件中

set $log = ngx_cycle->log
while $log->writer != ngx_log_memory_writer
    set $log = $log->next
end
set $buf = (ngx_log_memory_buf_t *) $log->wdata
dump binary memory debug_log.txt $buf->start $buf_end

按CTRL+D 退出gdb可以查看日志内容。

调试指定IP

可以在events段中指定要调试的IP地址或IP段。

events{
    debug_connection 192.168.1.1;
    debug_connection 192.18.10.0/24;
}
调试指定VS
error_log /path1/to/log debug;

http {
     server {
     error_log /path2/to/log debug;
     }
}

 

CoreDumps

可以通过操作系统,nginx两种方式进行配置

通过操作系统方式
  • 取消core dump 文件限制;
$ mkdir /tmp/cores
$ sudo chown root:root /tmp/cores
$ sudo chmod 1777 /tmp/cores
$ ulimit -c unlimited
or
$ sudo sh -c "ulimit -c unlimited && exec su $LOGNAME"
  • 指定文件名和目录

For CentOS 7.0, Debian 8.2, Ubuntu 14.04,

$ echo "/tmp/cores/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
$ sudo sysctl -w fs.suid_dumpable=2
$ sysctl -p

FreeBSD

$ sudo sysctl kern.sugid_coredump=1
$ sudo sysctl kern.corefile=/tmp/cores/%N.core.%P
通过nginx方式
  • 配置文件指定目录及大小限制
working_directory /tmp/cores/;
worker_rlimit_core 500M;
  • 设置目录权限
$ sudo chown root:root /tmp/cores
$ sudo chmod 1777 /tmp/cores

样例:

worker_processes   auto;
error_log          /var/log/nginx/error.log debug;
working_directory  /tmp/cores/;
worker_rlimit_core 500M;

events {
    ...
}

http {
    ...
}

获取coredump后可以通过bt执行查看crash时的堆栈信息定位问题。

$ sudo gdb <nginx_executable_path> <coredump_file_path>
(gdb) backtrace

 

导出配置文件

从运行的nginx master进程中导出配置文件, 需要可执行文件编译时使用–with-debug

set $cd = ngx_cycle->config_dump
set $nelts = $cd.nelts
set $elts = (ngx_conf_dump_t*)($cd.elts)
while ($nelts-- > 0) 
set $name = $elts[$nelts]->name.data
printf "Dumping %s to nginx_conf.txt\n", $name
append memory nginx_conf.txt \
      $elts[$nelts]->buffer.start $elts[$nelts]->buffer.end
end

使用场景:

  • 判断配置文件加载是否正确
  • 如果磁盘上的版本已意外删除或覆盖,则还原以前的配置

 

参考及引用

图片from 動感感

Comments are closed.