2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

使用新调试功能探测 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:583975
用户头像

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

关注

评论

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

阿里云混合云Apsara Stack 2.0发布,加速政企数智创新

架构 操作系统 公有云 科技

收藏!490家专精特新数智企业全名单:听听“小巨人”企业怎么说?

海比研究院

翻车了,字节一道 Fragment面试题

小松漫步

面试 大厂面试 Android;

Android架构之网络优化

轻口味

android 10月月更

10天拿到腾讯Android岗offer,内容太过真实

android 程序员 移动开发

达摩院求解器升级 覆盖黑盒优化难题

Lily

架构设计第一周学习总结

周文

总结思考

Week 1命题作业

小朱

架构实战营

数实融合·绽放新机,Techo Day技术回响日邀您“云相聚”

腾讯云数据库

数据库 tdsql

2021Android面试笔试总结!html5移动开发即学即用网盘

android 程序员 移动开发

金九银十,面试必备!耗时一周整理的牛客网上最火Java面试八股文

Java 程序员 架构 面试 大厂

同为aPaaS平台,华为云开天aPaaS与AppCube有何不同?

海比研究院

aPaaS

阿里云隐私增强计算产品DataTrust助力产业间实现数据价值高效协同

Lily

付费云存储,微信的登云梯还是蜀道难?

海比研究院

云存储

QCon看点|亚马逊云科技可持续软件工程实践分享

亚马逊云科技 (Amazon Web Services)

软件工程 S3 云端

2021Android进阶学习资料,动脑学院vip课程百度云

android 程序员 移动开发

SimpleDateFormat线程不安全了?这里有5种解决方案

华为云开发者联盟

安全 线程 变量 SimpleDateFormat

每秒创建百万文件,百度沧海·文件存储CFS推出新一代Namespace架构

百度大脑

人工智能

阿里云多个智物新品集体出道,持续加速产业智能化

Lily

会计CRM系统软件提高公司管理效率

低代码小观

企业 企业管理 管理会计综合实训平台 CRM 管理系统

docker 安装kafka

大可大大大

纵观移动云对象存储发展历程,也少不了 Apache APISIX 的能力加持

API7.ai 技术团队

API网关 企业案例 移动云 Apache APISIX

老凡尔赛了!当亚马逊云科技大佬“转行”讲起脱口秀

亚马逊云科技 (Amazon Web Services)

数字化转型 设计师

DeFi去中心化DAPP系统软件开发案例(现成)

官方线索|把梦想当作热爱,用技术创造价值!

搬砖人

1024我在现场

模块一作业

周文

「架构实战营」

阿里云正式开源PolarDB-X数据库,壮大云原生分布式数据库生态

Lily

DeFi平台挖矿系统需求开发(现成案例)

第 21 章 -《Linux 一学就会》- 结构化命令case和for、while循环

学神来啦

腾讯云,五轮面试,六个小时,灵魂拷问,含泪拿下 60W offer

进击的王小二

java面试 大厂面试 java

2021Android大厂面试题来袭,Android性能优化推荐书

android 程序员 移动开发

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