Skip to content

🚀 NGINX Debugger: The Ultimate Time-Saver for Lightning-Fast Configuration Fixes! 🔧

License

Notifications You must be signed in to change notification settings

FranklyCai/nginx-debugger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

中文文档 | English Documentation


NGINX 调试器

致力于打造最高效、最便捷、最全能的 NGINX 调试器


目录

NGINX Debugger 的由来

作为一名前端工程师,与 NGINX 打交道是我每天的工作日常。但与 NGINX 接触多了,我越来越觉得写 NGINX 的配置文件是一件 费时极容易出错 的活儿 (︶︹︶) —— NGINX 虽然功能强大,但配置指令 繁多复杂,即使是一点小的改动也可能带来翻天覆地的变化。因此,我们在写 NGINX 配置文件的时候必须慎之又慎!而在众多的 NGINX 配置项中,对我而言,location 块的配置就是噩梦中的噩梦 😭:

  • 首先,location 支持多种匹配方式,如 前缀匹配精确匹配正则匹配 等,不同的匹配方式还具有不同优先级,很容易搞混导致配置错误。

  • 其次,location 里可以搭配其它指令,如 rewritetry_filesproxy_pass 等,这些会让 NGINX 产生不同的行为:比如 rewrite 会修改 URL 地址,导致请求在 NGINX 内部进行跳转,进而匹配其它规则;try_files 有类似的效果;而 proxy_pass 则会修改请求的上游,将其转发至其它终端。

基于这种情况,我们在调试 NGINX 配置时,可能会发现一些“莫名其妙的 BUG” —— 比如我们明明预期某个请求应该命中 locationA ,但它却表现得像是命中了 locationB;又或者我们希望某个请求转发后完整的路径是 hostname:port/aaa/bbb/ccc,但实际上它转发出去的是 hostname:port/bbb/ccc

这些令人恼人的 “BUG” 其实是因为请求可能在 Nginx 的内部进行跳转,当请求一开始命中 locationA 的时候,由于 locationA 里可能有 rewrite 指令,重写后的请求刚好匹配到了 locationB;另外,Nginx 对 location 的匹配使用的是 Perl 的正则引擎,很多人对它了解并不多,再加上 proxy_pass 指令在将请求转发给上游时,它对上游 URI 的拼接其实分为很多种情况,不同情况下拼接出来的路径完全不一样。 因此,这些问题的调试其实是很麻烦的,有时候可能会花费大半天的时间 😞。

我曾经查阅多方资料,希望能找到一个好的解决方案,但结果一无所获。于是,我只好自己开发一个工具,来帮我省心高效地解决以上问题 —— NGINX Debugger 应运而生 🥳

NGINX Debugger 解决的问题

NGINX Debugger 尝试以最简单、最高效的方式解决上述所有问题,并遵守最佳实践。思考再三,我决定给 access.log 注册两个新变量: $upstream_uri$matched_locations,它们有以下用途:

  • $upstream_uri: Nginx 支持多种上游,包括 proxy_passfastcgi_passuwsgi_passscgi_pass等。无论你使用的是哪种上游,$upstream_uri 都能将 Nginx 拼接过后的最终完整地址展现出来。
  • $matched_locations: 如果 location 块使用了 rewrite 指令,那么请求可能在 Nginx 内部进行转发,且转发多次。使用$matched_locations能将这一过程以类似 locationA -> locationB -> locationC 的可视化形式展现出来,这样就我们可以清晰地把握每个请求在 Nginx 内部的流转情况,进而排除掉类似“明明应该命中 locationA,却命中了 locationB” 的奇怪 BUG 的出现。

如何使用

NGINX Debugger 可以在三个环境下使用:Windows、Linux 和 Docker

Windows

以下是 Windows 下编译 NGINX Debugger 的指令(配置参考链接:https://nginx.org/en/docs/howto_build_on_win32.html):

Windows编译指令

  • 使用方式一(全新安装):将该仓库的 nginx.exe 下载到本地,并在与它同文件夹下创建对应的文件与文件夹,如 conf/nginx.conflogs/access.loglogs/error.log

  • 使用方式二(替换安装):将该仓库的 nginx.exe 下载到本地,替换掉你本地已经安装的 nginx.exe

Linux

以下是Linux下编译Nginx Debugger的指令(配置参考链接:https://nginx.org/en/docs/configure.html):

Linux编译指令

  • 使用方式一(全新安装):将该仓库的 nginx 下载到 /usr/lib/nginx,并创建对应的文件与文件夹,如 /etc/nginx/nginx.conf/var/log/nginx/access.log/var/log/nginx/error.log

  • 使用方式二(替换安装):将该仓库的 nginx 下载到本地,替换掉你本地已经安装的 /usr/sbin/nginx

  • FAQ

    如果你使用的是方式二,且在启动 NGINX Debugger 的时候,发现控制台有类似以下提醒 模块版本不匹配 的报错:

    nginx: [emerg] module "/usr/lib/nginx/modules/ngx_http_geoip2_module.so" version 1018000 instead of 1027003 in /etc/nginx/modules-enabled/50-mod-http-geoip2.conf:1

    这是由于 NGINX Debugger 是基于最新的 🏷️1.27.2 版本进行编译的,而你本地安装的 Nginx 可能较低,因此导致模块的不匹配。你只需要将 nginx.conf 里引入 modules-enabled 的语句注释掉即可(如果你用不着这些模块的话)

    注释

Docker

Docker 版本的使用最为简单,你只需要使用以下指令拉取镜像即可:

docker pull franklycai/nginx-debugger

它基于 ubuntu/nginx:latest 进行构建。

参考配置

可以参照以下配置在 nginx.conf 里启用对 upstream_uri 和 matched_locations 的支持(仅供参考,实际可按需配置)

配置

技术细节

NGINX Debugger 是基于 NGINX 最新的 🏷️1.27.2 版本进行再创作的:它给 ngx_http_request_s 结构体新增了一个数组属性 ngx_array_t *matched_locations,用于存储 NGINX 匹配 location 的过程;又在 ngx_http_upstream.c 中注册了两个变量 —— upstream_uri 和 matched_locations,让我们可以在 access.log 里通过 $upstream_uri$matched_locations 获取 NGINX 转发的 完整上游地址 以及 location 的 完整匹配过程除此之外,代码没有做任何改动,整体框架保持不变。因此,你不用担心 NGINX 的工作模式发生了任何变化,也不用担心变量值的真实性与准确性,因为它们只是对 NGINX 内部变量的一点简单拼接、映射而已。

与其它工具的对比

Fiddler

Debugging and Troubleshooting Made Simple

  • 优点:Fiddler 是一款强大的网络调试代理工具,主要用于捕获、分析和调试 HTTP 和 HTTPS 网络请求。它界面美观,上手简单,是大多数人最先开始接触的网络调试工具。
  • 缺点:它无法捕获使用 Nginx 做代理转发的请求。因此,你无法从中获取 NGINX 究竟将你的请求转发到了何处,具体的请求路径是怎样的。另外一个小瑕疵在于,当你每次想要调试时,你都得重新打开 Fiddler,并且需要从它捕获到的大量 HTTP 与 HTTPS 请求中筛选出你想要的数据(除非你配置了 Filter)。

Wireshark

The world's most popular network protocol analyzer

  • 优点:Wireshark 是一款工作在底层的网络协议分析工具,它能够抓取并分析从链路层到应用层的所有数据,支持几乎所有的网络协议。
  • 缺点:功能强大也就意味着很难用好。Wireshark 相对于 Fiddler 来说,上手难度高出许多,很多新手甚至不知道该如何开始捕获请求 😂。其次,由于它支持几乎所有的协议(包括 HTTP、FTP、SMTP 等),你得从更多的数据里找到自己需要的部分,这难度无异于大上许多!最最最后,对于 Nginx 转发的 HTTPS 请求,你无法在 Wireshark 中找到它(因为 HTTPS 对流量进行了加密,而 Wireshark 没有使用类似 Fiddler 的中间人代理技术,因此无法查看里面的内容)

error.log

Nginx 官方的错误日志

  • 优点:系统自带,可以显示很多调试信息。
  • 缺点:一般情况下只显示严重错误,如果你需要更多信息,需要在配置文件中显式开启 debug 选项并重启 Nginx。对于某个特定的请求,它的调试信息会跨越多行,并且中间穿插一些不相干的信息,你需要仔细辨别将它们关联起来。请求与请求之间分隔并不明显,很容易误将一个请求的信息当成另一个请求的信息了 😒。最后,即使你开启了 debug 选项,你也无法从日志文件中得到 Nginx 究竟将请求转发到了哪里,完整路径是怎么样的,因为 Nginx 压根不会记录这些东西。

总结

调试工具 是否支持查看 upstream 是否支持查看 location 的匹配过程 是否简单高效
NGINX Debugger 支持 支持 ⭐⭐⭐⭐⭐
Fiddler 经 NGINX 转发的不支持 不支持 ⭐⭐⭐☆☆
Wireshark 支持 HTTP、不支持 HTTPS 不支持 ⭐⭐⭐☆☆
error.log 不支持 支持 ⭐⭐⭐☆☆

NGINX Debugger 就是为解决这些问题而生的!如果你也曾像我一样深受 Nginx 配置的困扰,试一下这个工具吧,也许会为你打开不一样的视界!

许可证

2-clause BSD-like license

About

🚀 NGINX Debugger: The Ultimate Time-Saver for Lightning-Fast Configuration Fixes! 🔧

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published