HTTP 404・502・504发生在哪一层?——从Nginx与应用的通信路径进行排查

ネットワーク・RFCカテゴリを表すパンダのイラスト 网络・RFC

关于本文
本文采用生成式AI辅助自动化流程创建。我们查阅了RFC 9110的HTTP状态定义以及Nginx官方的proxy/FastCGI文档,将其整理为可用于Web故障初步排查的形式。

验证状态:🧪 已确认RFC及Nginx官方信息・已在localhost确认404・未进行502/504的故意复现

HTTP 404・502・504发生在哪一层?——从Nginx与应用的通信路径进行排查

404502504 都是HTTP状态码,但它们的含义并不相同。如果将Nginx作为反向代理或FastCGI的入口,切勿仅凭状态码断定原因,而应确认处理流程进行到了浏览器 → Nginx → upstream的哪一步

首先厘清HTTP层面的含义

Status简述RFC中的含义首先考虑的事项
404 Not Found源服务器找不到目标资源的当前表现形式,或者不想透露其是否存在URL・路由・静态文件・应用侧路由
502 Bad Gateway网关/代理从上游收到了无效的响应upstream连接目标・协议・服务・socket
504 Gateway Timeout网关/代理未能在规定时间内从上游获得必要的响应upstream延迟・超时・堵塞

重要的一点是,不要直接将其与 502 = PHPの文法エラー504 = Nginxが壊れた 等产品特定的原因挂钩。RFC定义的是HTTP响应的含义,而实际原因会因架构配置而异。

有Nginx居中时,通信路径会增加

sequenceDiagram
    participant B as Browser
    participant N as Nginx
    participant U as Upstream / PHP-FPM
    B->>N: HTTP request
    alt Nginx自身で処理
        N-->>B: 2xx / 4xx など
    else upstreamへ転送
        N->>U: proxy_pass / fastcgi_pass
        U-->>N: response または失敗
        N-->>B: HTTP response
    end

即便是同样的 404,通过Nginx静态文件查找返回的404与由upstream应用返回的404,其排查位置也有所不同。因此,第一步是确认“是谁生成了该响应”

遇到404时切勿只看URL

遇到404时,请按顺序确认以下内容:

  1. 浏览器请求的path是否符合预期

  2. Nginx的 location 将请求分发到了哪里

  3. 如果是静态文件,实际文件与root/alias的关系是否正确

  4. 如果是upstream应用,该路由是否真的存在

此外,根据RFC 9110,当服务器不想透露目标资源是否存在时也可以使用404,因此不能仅仅因为出现404就断定“物理文件不存在”。

遇到502时检查与upstream的边界

Nginx的 proxy_passfastcgi_pass 适用于Nginx前方还有其他服务器或FastCGI进程的架构。如果出现502,例如需要确认以下内容:

  • upstream的主机、端口或Unix socket是否正确

  • upstream进程是否已启动

  • 是否具备从Nginx进行连接的权限和网络路径

  • 通信对象使用的是HTTP协议还是FastCGI协议

  • error log中是否留下了连接upstream时的具体失败记录

不仅是“上游宕机”,连接目标的错配或socket权限问题也会导致通信边界损坏。

遇到504时寻找“变慢的地方”

504是指网关/代理未能在规定时间内接收到上游响应的状态。在盲目增大timeout值之前,请先确认upstream侧的处理是否停滞,或者对外部API及数据库的等待时间是否过长。

如果仅仅通过延长timeout来掩盖症状,有时反而会耽误根本原因的发现。

立即尝试:在localhost上真正触发一次404

不仅是纸上谈兵,我们首先在自己的电脑上观察404。无需修改Nginx配置,只需通过 127.0.0.1 启动一个Python简易HTTP服务器即可。

终端1:

python3 -m http.server 8000 --bind 127.0.0.1

终端2:

curl -i http://127.0.0.1:8000/not-found

由于并没有创建 not-found 这个文件,简易HTTP服务器会返回 404 File not found。通过这种方式,可以安全地确认“404确实会作为HTTP响应返回”。

在排查实际网站故障时,有时我们不想显示大量正文,只想查看status、header和连接目标。在GitHub示例中可以这样使用:

./check-http-status.sh https://example.com/

主要显示的内容为response header、HTTP status、remote IP和total time。请将URL替换为您要检查的目标。

为了学习502或504,没有必要故意破坏生产环境Nginx的upstream配置。更安全的做法是:先观察status,如果是502则检查与upstream的连接边界,如果是504则检查upstream的处理时间或timeout设置。

初步排查

flowchart TD
    A[HTTPエラーを確認] --> B{404?}
    B -- はい --> C[URL / location / route / fileを確認]
    B -- いいえ --> D{502?}
    D -- はい --> E[upstream接続・socket・protocol・logを確認]
    D -- いいえ --> F{504?}
    F -- はい --> G[upstream処理時間・timeout・依存先を確認]
    F -- いいえ --> H[別のstatus定義へ]

GitHub示例

官方信息与一手资料

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
标题和URL已复制