Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/franklycai/nginx-debugger

🚀 NGINX Debugger: The Ultimate Time-Saver for Lightning-Fast Configuration Fixes! 🔧
https://github.com/franklycai/nginx-debugger

debugger efficiency frontend-development javascript nginx nginx-debugger

Last synced: 2 months ago
JSON representation

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

Awesome Lists containing this project

README

        



中文文档 | English Documentation





NGINX 调试器

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



## 目录

- [NGINX Debugger 的由来](#nginx-debugger-的由来)
- [NGINX Debugger 解决的问题](#nginx-debugger-解决的问题)
- [如何使用](#如何使用)
- [Windows](#windows)
- [Linux](#linux)
- [FAQ](#faq)
- [Docker](#docker)
- [参考配置](#参考配置)
- [技术细节](#技术细节)
- [与其它工具的对比](#与其它工具的对比)
- [Fiddler](#fiddler)
- [Wireshark](#wireshark)
- [error.log](#errorlog)
- [总结](#总结)
- [许可证](#许可证)

## 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_pass`、`fastcgi_pass`、`uwsgi_pass` 和 `scgi_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.conf` 和 `logs/access.log`、`logs/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` 的时候,发现控制台有类似以下提醒 模块版本不匹配 的报错:

```bash
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](https://github.com/nginx/nginx/commit/e24f7ccc161f1a2a759eb27263ec9af4fc7c8e96) 版本进行编译的,而你本地安装的 Nginx 可能较低,因此导致模块的不匹配。你只需要将 nginx.conf 里引入 `modules-enabled` 的语句注释掉即可(如果你用不着这些模块的话)

注释

### Docker

Docker 版本的使用最为简单,你只需要使用以下指令拉取镜像即可:
```bash
docker pull franklycai/nginx-debugger
```
它基于 [ubuntu/nginx:latest](https://hub.docker.com/r/ubuntu/nginx) 进行构建。

## 参考配置

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

![配置](assets/configuration.png)

## 技术细节

NGINX Debugger 是基于 NGINX 最新的 🏷️[1.27.2](https://github.com/nginx/nginx/commit/e24f7ccc161f1a2a759eb27263ec9af4fc7c8e96) 版本进行再创作的:它给 `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](LICENSE.txt)