{"id":21189968,"url":"https://github.com/franklycai/nginx-debugger","last_synced_at":"2025-07-10T02:32:25.474Z","repository":{"id":262274730,"uuid":"886727408","full_name":"FranklyCai/nginx-debugger","owner":"FranklyCai","description":"🚀 NGINX Debugger: The Ultimate Time-Saver for Lightning-Fast Configuration Fixes! 🔧","archived":false,"fork":false,"pushed_at":"2024-11-19T04:49:18.000Z","size":5063,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-19T05:28:57.191Z","etag":null,"topics":["debugger","efficiency","frontend-development","javascript","nginx","nginx-debugger"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FranklyCai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-11T13:50:51.000Z","updated_at":"2024-11-19T05:04:35.000Z","dependencies_parsed_at":"2024-11-11T15:32:53.592Z","dependency_job_id":"affb9bce-9457-488a-9d02-04a290e7e95f","html_url":"https://github.com/FranklyCai/nginx-debugger","commit_stats":null,"previous_names":["franklycai/nginx-debugger"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranklyCai%2Fnginx-debugger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranklyCai%2Fnginx-debugger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranklyCai%2Fnginx-debugger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FranklyCai%2Fnginx-debugger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FranklyCai","download_url":"https://codeload.github.com/FranklyCai/nginx-debugger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225615230,"owners_count":17496942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debugger","efficiency","frontend-development","javascript","nginx","nginx-debugger"],"created_at":"2024-11-20T18:59:02.529Z","updated_at":"2024-11-20T18:59:03.335Z","avatar_url":"https://github.com/FranklyCai.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cdiv\u003e\n  中文文档\u0026emsp;|\u0026emsp;\u003ca href=\"README.en.md\"\u003eEnglish Documentation\u003c/a\u003e\n  \u003c/div\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"assets/nginx-debugger.png\" alt=\"NGINX 调试器\"\u003e\n\u003cbr\u003e\n\n# 致力于打造最高效、最便捷、最全能的 NGINX 调试器\n\n\u003c/div\u003e\n\u003cbr\u003e\n\n## 目录\n\n- [NGINX Debugger 的由来](#nginx-debugger-的由来)\n- [NGINX Debugger 解决的问题](#nginx-debugger-解决的问题)\n- [如何使用](#如何使用)\n  - [Windows](#windows)\n  - [Linux](#linux)\n    - [FAQ](#faq)\n  - [Docker](#docker)\n- [参考配置](#参考配置)\n- [技术细节](#技术细节)\n- [与其它工具的对比](#与其它工具的对比)\n  - [Fiddler](#fiddler)\n  - [Wireshark](#wireshark)\n  - [error.log](#errorlog)\n  - [总结](#总结)\n- [许可证](#许可证)\n\n## NGINX Debugger 的由来\n\n作为一名前端工程师，与 NGINX 打交道是我每天的工作日常。但与 NGINX 接触多了，我越来越觉得写 NGINX 的配置文件是一件 \u003cb\u003e费时\u003c/b\u003e 且 \u003cb\u003e极容易出错\u003c/b\u003e 的活儿 (︶︹︶) —— NGINX 虽然功能强大，但配置指令 \u003cb\u003e繁多\u003c/b\u003e 且 \u003cb\u003e复杂\u003c/b\u003e，即使是一点小的改动也可能带来翻天覆地的变化。因此，我们在写 NGINX 配置文件的时候必须慎之又慎！而在众多的 NGINX 配置项中，对我而言，`location` 块的配置就是噩梦中的噩梦 😭：\n\n- 首先，`location` 支持多种匹配方式，如 \u003cb\u003e前缀匹配\u003c/b\u003e、\u003cb\u003e精确匹配\u003c/b\u003e、\u003cb\u003e正则匹配\u003c/b\u003e 等，不同的匹配方式还具有\u003cb\u003e不同优先级\u003c/b\u003e，很容易搞混导致配置错误。\n\n- 其次，`location` 里可以搭配其它指令，如 \u003cb\u003erewrite\u003c/b\u003e、\u003cb\u003etry_files\u003c/b\u003e、\u003cb\u003eproxy_pass\u003c/b\u003e 等，这些会让 NGINX 产生不同的行为：比如 \u003ci\u003erewrite\u003c/i\u003e 会修改 URL 地址，导致请求在 NGINX 内部进行跳转，进而匹配其它规则；\u003ci\u003etry_files\u003c/i\u003e 有类似的效果；而 \u003ci\u003eproxy_pass\u003c/i\u003e 则会修改请求的上游，将其转发至其它终端。\n\n基于这种情况，我们在调试 NGINX 配置时，可能会发现一些\u003cb\u003e“莫名其妙的 BUG”\u003c/b\u003e —— 比如我们明明预期某个请求应该命中 `locationA` ，但它却表现得像是命中了 `locationB`；又或者我们希望某个请求转发后完整的路径是 `hostname:port/aaa/bbb/ccc`，但实际上它转发出去的是 `hostname:port/bbb/ccc`。\n\n这些令人恼人的 “BUG” 其实是因为请求可能在 Nginx 的内部进行跳转，当请求一开始命中 `locationA` 的时候，由于 `locationA` 里可能有 `rewrite` 指令，重写后的请求刚好匹配到了 `locationB`；另外，Nginx 对 `location` 的匹配使用的是 Perl 的正则引擎，很多人对它了解并不多，再加上 `proxy_pass` 指令在将请求转发给上游时，它对上游 URI 的拼接其实分为很多种情况，不同情况下拼接出来的路径完全不一样。 因此，这些问题的调试其实是很麻烦的，有时候可能会花费大半天的时间 😞。\n\n我曾经查阅多方资料，希望能找到一个好的解决方案，但结果一无所获。于是，我只好自己开发一个工具，来帮我省心高效地解决以上问题 —— \u003cb\u003eNGINX Debugger\u003c/b\u003e 应运而生 🥳\n\n## NGINX Debugger 解决的问题\n\nNGINX Debugger 尝试以最简单、最高效的方式解决上述所有问题，并遵守最佳实践。思考再三，我决定给 \u003cb\u003eaccess.log\u003c/b\u003e 注册两个新变量： \u003cb\u003e$upstream_uri\u003c/b\u003e 和 \u003cb\u003e$matched_locations\u003c/b\u003e，它们有以下用途：\n\n- \u003cb\u003e$upstream_uri\u003c/b\u003e: Nginx 支持多种上游，包括 `proxy_pass`、`fastcgi_pass`、`uwsgi_pass` 和 `scgi_pass`等。无论你使用的是哪种上游，`$upstream_uri` 都能将 Nginx 拼接过后的最终完整地址展现出来。\n- \u003cb\u003e$matched_locations\u003c/b\u003e: 如果 `location` 块使用了 `rewrite` 指令，那么请求可能在 Nginx 内部进行转发，且转发多次。使用`$matched_locations`能将这一过程以类似 `locationA -\u003e locationB -\u003e locationC` 的可视化形式展现出来，这样就我们可以清晰地把握每个请求在 Nginx 内部的流转情况，进而排除掉类似“明明应该命中 locationA，却命中了 locationB” 的奇怪 BUG 的出现。\n\n## 如何使用\n\nNGINX Debugger 可以在三个环境下使用：Windows、Linux 和 Docker\n\n### Windows\n\n以下是 Windows 下编译 NGINX Debugger 的指令（配置参考链接：https://nginx.org/en/docs/howto_build_on_win32.html）：\n\n\u003cimg src=\"assets/windows_cmd_zh.png\" alt=\"Windows编译指令\"\u003e\n\n- 使用方式一（全新安装）：将该仓库的 `nginx.exe` 下载到本地，并在与它同文件夹下创建对应的文件与文件夹，如 `conf/nginx.conf` 和 `logs/access.log`、`logs/error.log` 等\n\n- 使用方式二（替换安装）：将该仓库的 `nginx.exe` 下载到本地，替换掉你本地已经安装的 `nginx.exe`\n\n### Linux\n\n以下是Linux下编译Nginx Debugger的指令（配置参考链接：https://nginx.org/en/docs/configure.html）：\n\n\u003cimg src=\"assets/linux_cmd_zh.png\" alt=\"Linux编译指令\"\u003e\n\n- 使用方式一（全新安装）：将该仓库的 `nginx` 下载到 `/usr/lib/nginx`，并创建对应的文件与文件夹，如 `/etc/nginx/nginx.conf` 和 `/var/log/nginx/access.log`、`/var/log/nginx/error.log` 等\n\n- 使用方式二（替换安装）：将该仓库的 `nginx` 下载到本地，替换掉你本地已经安装的 `/usr/sbin/nginx`\n\n- #### FAQ\n\n  如果你使用的是方式二，且在启动 `NGINX Debugger` 的时候，发现控制台有类似以下提醒 \u003cb\u003e模块版本不匹配\u003c/b\u003e 的报错：\n\n  ```bash\n  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\n  ```\n\n  这是由于 `NGINX Debugger` 是基于最新的 🏷️[1.27.2](https://github.com/nginx/nginx/commit/e24f7ccc161f1a2a759eb27263ec9af4fc7c8e96) 版本进行编译的，而你本地安装的 Nginx 可能较低，因此导致模块的不匹配。你只需要将 nginx.conf 里引入 `modules-enabled` 的语句注释掉即可（如果你用不着这些模块的话）\n\n  \u003cimg src=\"assets/comment.png\" alt=\"注释\"\u003e\n\n### Docker\n\nDocker 版本的使用最为简单，你只需要使用以下指令拉取镜像即可：\n```bash\ndocker pull franklycai/nginx-debugger\n```\n它基于 [ubuntu/nginx:latest](https://hub.docker.com/r/ubuntu/nginx) 进行构建。\n\n## 参考配置\n\n可以参照以下配置在 nginx.conf 里启用对 upstream_uri 和 matched_locations 的支持（仅供参考，实际可按需配置）\n\n![配置](assets/configuration.png)\n\n## 技术细节\n\nNGINX 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，让我们可以在 \u003ci\u003eaccess.log\u003c/i\u003e 里通过 `$upstream_uri` 和 `$matched_locations` 获取 NGINX 转发的 \u003ci\u003e完整上游地址\u003c/i\u003e 以及 location 的 \u003ci\u003e完整匹配过程\u003c/i\u003e。\u003cb\u003e除此之外，代码没有做任何改动，整体框架保持不变。\u003c/b\u003e因此，你不用担心 NGINX 的工作模式发生了任何变化，也不用担心变量值的真实性与准确性，因为它们只是对 NGINX 内部变量的一点简单拼接、映射而已。\n\n## 与其它工具的对比\n\n### Fiddler\n\n\u003e \u003csmall\u003eDebugging and Troubleshooting Made Simple\u003c/small\u003e\n\n- 优点：Fiddler 是一款强大的网络调试代理工具，主要用于捕获、分析和调试 HTTP 和 HTTPS 网络请求。它界面美观，上手简单，是大多数人最先开始接触的网络调试工具。\n- 缺点：\u003cb\u003e它无法捕获使用 Nginx 做代理转发的请求\u003c/b\u003e。因此，你无法从中获取 NGINX 究竟将你的请求转发到了何处，具体的请求路径是怎样的。另外一个小瑕疵在于，当你每次想要调试时，你都得重新打开 Fiddler，并且需要从它捕获到的大量 HTTP 与 HTTPS 请求中筛选出你想要的数据（除非你配置了 Filter）。\n\n### Wireshark\n\n\u003e The world's most popular network protocol analyzer\n\n- 优点：Wireshark 是一款工作在底层的网络协议分析工具，它能够抓取并分析从链路层到应用层的所有数据，支持几乎所有的网络协议。\n- 缺点：功能强大也就意味着很难用好。Wireshark 相对于 Fiddler 来说，上手难度高出许多，很多新手甚至不知道该如何开始捕获请求 😂。其次，由于它支持几乎所有的协议（包括 HTTP、FTP、SMTP 等），你得从更多的数据里找到自己需要的部分，这难度无异于大上许多！\u003cb\u003e最最最后，对于 Nginx 转发的 HTTPS 请求，你无法在 Wireshark 中找到它\u003c/b\u003e（因为 HTTPS 对流量进行了加密，而 Wireshark 没有使用类似 Fiddler 的中间人代理技术，因此无法查看里面的内容）\n\n### error.log\n\n\u003e Nginx 官方的错误日志\n\n- 优点：系统自带，可以显示很多调试信息。\n- 缺点：一般情况下只显示严重错误，如果你需要更多信息，需要在配置文件中显式开启 `debug` 选项并重启 Nginx。\u003cb\u003e对于某个特定的请求，它的调试信息会跨越多行\u003c/b\u003e，并且中间穿插一些不相干的信息，你需要仔细辨别将它们关联起来。\u003cb\u003e请求与请求之间分隔并不明显\u003c/b\u003e，很容易误将一个请求的信息当成另一个请求的信息了 😒。最后，即使你开启了 `debug` 选项，你也\u003cb\u003e无法从日志文件中得到 Nginx 究竟将请求转发到了哪里，完整路径是怎么样的\u003c/b\u003e，因为 Nginx 压根不会记录这些东西。\n\n### 总结\n\n| 调试工具       | 是否支持查看 upstream   | 是否支持查看 location 的匹配过程 | 是否简单高效 |\n| -------------- | ----------------------- | -------------------------------- | ------------ |\n| NGINX Debugger | 支持                    | 支持                             | ⭐⭐⭐⭐⭐   |\n| Fiddler        | 经 NGINX 转发的不支持   | 不支持                           | ⭐⭐⭐☆☆     |\n| Wireshark      | 支持 HTTP、不支持 HTTPS | 不支持                           | ⭐⭐⭐☆☆     |\n| error.log      | 不支持                  | 支持                             | ⭐⭐⭐☆☆     |\n\n\u003cb\u003eNGINX Debugger 就是为解决这些问题而生的！\u003c/b\u003e如果你也曾像我一样深受 Nginx 配置的困扰，试一下这个工具吧，也许会为你打开不一样的视界！\n\n## 许可证\n\n[2-clause BSD-like license](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranklycai%2Fnginx-debugger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffranklycai%2Fnginx-debugger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranklycai%2Fnginx-debugger/lists"}