10 月 23 - 25 日,QCon 上海站即将召开,现在大会已开始正式报名,可以享受 8 折优惠 了解详情
写点什么

使用新调试功能探测 Nginx 内核

  • 2015-09-01
  • 本文字数:2531 字

    阅读完需:约 8 分钟

Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的一个高性能 HTTP 和反向代理服务器,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日,最新的版本已经到 1.9.3。Nginx 也是一个 IMAP/POP3/SMTP 服务器,还可作为 Web 服务器、负载均衡服务器。Nginx 将源代码以类 BSD 许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

从 Nginx 关于调试工具的官方网页来看,在 Nginx 最近的版本中,增加了很多有用的调试功能,通过使用 GDB 从运行的服务器中提取信息。虽然现在并不建议在生产环境的 Nginx 上使用 GDB,但其在开发或测试环境下是非常有用的。

本文要介绍的新的功能包括了建立 Nginx 时的–with-debug 配置选项。为了确定文件是否内置了这个选项,运行 nginx -V 命令:

复制代码
# nginx -V
nginx version nginx/1.9.3
built by gcc 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC)
configure arguments: --with-debug --prefix-/opt/nginx-debug

在内存中编写调试日志

第一个新功能是在内存中的调试日志。Nginx 调试日志对于挖掘复杂的问题非常有用。在以前的版本当中,调试日志存储在磁盘空中,但由于日志文件可能会迅速变得非常大,导致占用大量的磁盘空间。

Nginx 1.7.11 增加了使用循环缓冲区(cyclic memory buffer)直接访问内存的能力,使得调试日志完全不用使用磁盘存储。有关详细信息,请参阅 Nginx 文档中 <a href="http://nginx.org/en/docs/debugging_log.html?&_ga=1.228176989.1157264337.1438403117#memory"> 循环内存缓冲区 </a>。要启用一个 32 MB 的缓冲区调试日志记录,在 Nginx 配置文件的主环境下,使用 error_log 指令:

error_log memory:32m debug;``可以使用 GDB 从内存中提取日志。 同时可以到 <a href="https://gist.github.com/LinuxJedi/ae68bf582068395de317"> 此处 </a> 下载一个 GitHub Gist,里面包含了文章中介绍的例子所需要的所有东西。下载并保存为 Nginx.gdb,或在 home 目录下重新命名为.gdbinit,让其自动加载。

首先,运行以下命令可以显示 Nginx 工作进程的进程 ID:

# pgrep -f "nginx: worker"``找到探测对象的进程 ID。在这个例子中,有一个 ID 为 20192 的工作进程,要启动 GDB 并加载工作进程,运行以下命令(请注意,当 GDB 运行的时候,工作进程被暂停):

# sudo gdb --pid 20192``加载从 GitHub Gist 上下载的脚本并转储调试日志,运行以下命令:

复制代码
(gdb) source nginx.gdb
(gdb) ddl

GDB 创建了一个名为 debug_log.txt 的文件,里面包含了使用 error_log 指令分配的内存转储,因此在这个例子中的文件大小为 32 MB。可以轻松使用下面的 sed 命令截断它。在大多数情况下,不需要这样做,如果日志文件已经打包,该命令无效:

# sed -i 's/[[:space:]]*$//' debug_log.txt``显然,在探测日志的时候让工作进程暂停并不总是一个好办法。所以,可以将暂停的时间限制得非常短,如果超出时间限制,告诉 GDB 要探测日志并让工作进程立刻停止,这种办法很常用,更多细节可以参考 <a href="http://poormansprofiler.org/"> 这里 </a>。

# gdb --pid 20192 -iex "source nginx.gdb" -ex "ddl" –batch## 转储活动 Nginx 配置

在 Nginx 1.9.2 及以后的版本中,当 Nginx 使用 --with-debug 配置选项进行建立的时候,整个配置存储在内存中,从而可以使用 GDB 从主进程中提取配置。这可能是很有用的,可以用来核实哪些配置已经被加载,如果磁盘上的版本已经被意外删除或覆盖的时候可以帮助恢复之前的配置。

和前面一样,<a href="https://gist.github.com/LinuxJedi/ae68bf582068395de317">GitHub Gist</a> 中的 nginx.gdb 文件也包含了运行内存转储的功能。因此,首先载入 GDB:

# sudo gdb --pidpgrep -f “nginx: master”```然后,运行以下命令来转储配置。`

(gdb) source nginx.gdb (gdb) dcfg``在转储它们的时候,GDB 输出文件的名称。例如,这个例子中的输出,每个文件名的末尾可能有一些乱码,这是因为当字符串没有 NUL 终止的时候,GDB 的 printf 函数不是一直运行得很好。最后的结果是一个包含完整活动配置的名为 nginx_conf.txt 的文件。

<img src="https://static001.infoq.cn/resource/image/cd/16/cd07f9a3e67e289c7e859d76d1b15a16.png"></img>

在使用调试日志的时候,还可以使用批处理模式转储配置:

# gdb --pidpgrep -f “nginx: master”-iex "source nginx.gdb" -ex "dcfg" –batch## 用 core 文件使用 GDB

文章中涵盖的所有东西都可以用来帮助使用 core 文件调试问题产生的原因:

# gdb --core core.9491 nginx``无论是在这篇文章中描述的 dcfg 函数还是 ddl 函数,都可以用作 core 文件。如果需要在 core 文件生成的时候找到 NGINX 服务器的配置,或者需要为导致 core 文件生成的事件找到调试信息,这可能会有用。

对于提取关于 Nginx 内核的信息,转储调试日志和配置都是非常有用的方法,当然也可以通过调整 GDB 的脚本,在文章介绍的技术的基础上进行拓展。例如,转储配置时,可以转储每个加载的配置文件到一个单独的输出文件中,而不是转储所有东西到单独的一个文件中。文件名的长度用文件名自身存储,所以要使用它们的时候,应该有一种方法要么复制它们要么截断它们,标准 API 脚本是一种非常好的方式,GDB 最近的版本开始支持 Python 脚本,也提供了一种选择。

值得重申的是,这些技术仅仅建议在开发和测试环境中使用。暂停 Nginx 过程不是一个好主意,尤其是在生产环境下。


感谢 <a href="http://www.infoq.com/cn/author/%E9%AD%8F%E6%98%9F"> 魏星 </a> 对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 <a href="mailto:editors@cn.infoq.com">editors@cn.infoq.com</a>。也欢迎大家通过新浪微博(<a href="http://www.weibo.com/infoqchina">@InfoQ</a>,<a href="http://weibo.com/u/1451714913">@丁晓昀 </a>),微信(微信号:<a href="http://weixin.sogou.com/gzh?openid=oIWsFt0HnZ93MfLi3pW2ggVJFRxY">InfoQChina</a>)关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群 <a href="http://shang.qq.com/wpa/qunwpa?idkey=cc82a73d7522f0090aa3cbb6a8f4bdafa8b82177f481014c976a8740d927997a" target="_blank"><img src="https://static001.infoq.cn/resource/image/06/9f/06e1fec4a87eca3142d54d09844c629f.png"></img></a>)。

2015-09-01 18:583825
用户头像

发布了 268 篇内容, 共 133.4 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

开鸿智谷与华秋达成生态共创合作,共同打造硬件生态

华秋电子

软件测试/测试开发丨Linux进程与线程学习笔记

测试人

Python Linux 程序员 软件测试

转型过程“千变万化”,怎样的数智平台才能够帮助企业顺利转型?

用友BIP

数智底座

对线面试官 Redis | 十 Redis集群模式

派大星

Java 面试题

融云「北极星」数据监控平台:数据可视通晓全局,精准分析定位问题

融云 RongCloud

监控 数据 IM RTC 融云

智能分析云 | 穿透式数据分析赋能数智国资

用友BIP

数据分析

Github实时数据分析与可视化训练营火热开启!免费领取5000元云上资源

阿里云大数据AI技术

MySQL 开发者 分布式计算 数据可视化 大数据、

Karmada:让跨集群弹性伸缩FederatedHPA突破新边界

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

点云标注的未来发展与技术革新

数据堂

润和软件与华秋达成生态共创合作,共同推动物联网硬件创新

华秋电子

CST电磁仿真软件要怎么学?

思茂信息

操作 仿真软件 cst cst使用教程 cst仿真软件

尝试7分钟内上线一个网站,这个工具太赞了!

互联网工科生

低代码 搭建平台 搭建网站

2023年中国(深圳)国际耐火材料产业展会

秋硕展览

软通动力与华秋达成生态共创合作,共同推动物联网硬件创新

华秋电子

@Import :Spring Bean模块装配的艺术

华为云开发者联盟

spring 开发 华为云 华为云开发者联盟 企业号 7 月 PK 榜

华秋慕尼黑上海电子展圆满收官,数字化赋能智能制造!

华秋电子

MQTT 订阅标识符详解

EMQ映云科技

mqtt 订阅标识符

2023中国老博会/2023西部养老辅具展会

秋硕展览

企业转型必修课,用友BIP成为企业数智化首选

用友BIP

国产替代

共筑信创生态!亚信科技AntDB数据库与用友、东方通、星辰天合达成兼容互认

亚信AntDB数据库

数据库 AntDB AntDB数据库

软件测试/测试开发丨Linux常用命令之性能统计

测试人

Python Linux 程序员 性能 软件测试

Java基础入门——Java语言介绍

java易二三

Java

“芯”有灵“蜥” 融合·创新!龙蜥社区走进 Intel MeetUp 议程硬核剧透来了

OpenAnolis小助手

开源 操作系统 intel Meetup 龙蜥社区

深开鸿与华秋达成生态共创合作,共同打造硬件生态

华秋电子

Spring 能解决所有循环依赖吗?

江南一点雨

Java spring

开发微信公众号本地调试+-+cpolar内网穿透

程思扬

微信公众号 网络穿透

Eplan是什么软件?学习Eplan软件的几个关键要点

智造软件

汽车电气架构 CAE CAE软件 EPLAN 电气辅助设计

使用新调试功能探测Nginx内核_语言 & 开发_张天雷_InfoQ精选文章