很多线上排障都是从一个状态码开始的,比如 404、403、499、502、504。问题在于,很多人只记住了“这些码大概代表什么”,却没有建立它们和真实代理链路之间的联系。结果就是看到 502 就怀疑服务挂了,看到 404 就觉得文件没了,最后排查方向经常一开始就偏掉。

状态码只是结果,不是原因。真正有价值的,是把状态码放回请求链路里去看:这个错误是客户端到 Nginx 这段产生的,还是 Nginx 到上游那段产生的,又或者根本是匹配规则导致的。

为什么 Nginx 的状态码特别值得单独看

因为 Nginx 既可能直接生成状态码,也可能只是把上游状态原样转给客户端,还可能在中间代理过程中重新包装错误。

这意味着同样一个 404,可能是。

  • Nginx 本地静态路径未命中。
  • 站点匹配错了。
  • 上游服务返回了 404。

同样一个 502,也可能是。

  • Nginx 无法连接上游。
  • 上游返回了非法响应。
  • TLS 回源握手失败。
  • 上游在代理阶段直接断开。

所以状态码不能孤立看,必须结合链路和日志一起看。

先分清 4xx 和 5xx 大致在说什么

粗略来说,4xx 更常见于客户端请求不符合当前入口规则,或者请求根本没有正确命中资源;5xx 更常见于代理层和上游之间的处理失败。

但这只是第一层判断,不能直接当结论。

例如 499 就非常典型,它常常不是源站错误,而是客户端在 Nginx 返回结果前主动断开了连接。你如果只把它当成普通 4xx 去理解,结论就会完全错误。

最值得先建立直觉的几个状态码

404

在 Nginx 场景里,404 很容易让人误以为“文件没找到”。但实际更常见的是路径没有命中你预期的 location,或者根本进了一个错误的站点配置。

如果是代理场景,还要继续分清 404 是 Nginx 自己返回的,还是上游服务返回的。

403

403 常见于访问控制、目录权限、白名单、鉴权逻辑或静态目录权限不符合要求。它往往比 404 更偏“规则阻止”,而不是“资源不存在”。

499

这是 Nginx 场景里非常值得单独理解的状态码。它表示客户端先断开了连接。很多人第一次看到时会紧张,以为服务报错了,其实它更像是一个“客户端已经不等了”的现场信号。

502

502 常常意味着 Nginx 作为网关从上游拿到了异常结果,或者根本没能成功和上游建立一个有效代理通道。它非常值得优先结合错误日志和上游连通性一起排。

504

504 更常见于代理等待超时。它不一定代表上游彻底挂了,更可能是上游处理太慢、回源链路慢,或者某一层超时时间设置太紧。

排查这些状态码时最实用的思路

第一步,不要先猜,先复现最小现场。

1
curl -I -v https://example.com/path

先确认。

  • 返回码是什么。
  • 有没有发生重定向。
  • 响应头是否能看出是 Nginx 直接返回还是上游返回。

第二步,去看访问日志和错误日志。

访问日志能告诉你请求确实有没有到达 Nginx,错误日志则更适合看代理失败、上游连接失败、超时、握手异常等现场。

第三步,把问题放回链路里判断。

  • 4xx 更偏入口匹配、权限和客户端行为。
  • 502 / 504 更偏代理链路和上游状态。
  • 499 更偏客户端等待行为和超时体验。

第四步,再决定是否继续看上游服务、源站日志、TLS 回源或网络链路。

一个简单但很有用的判断习惯

如果你看到 502 或 504,不要第一反应就是“后端挂了”,而是先问自己三个问题。

  • Nginx 有没有连上上游。
  • 连上之后,是不是收到了异常响应。
  • 这个异常更像超时、拒绝、握手失败,还是上游主动断开。

这个习惯非常重要,因为很多代理层问题,如果一开始就直接进应用代码排,会浪费很多时间。

常见误判

最常见的误判之一,是把所有 404 都当静态资源问题。实际上,域名匹配错、路径改写错、代理到错误上游,都可能表现成 404。

第二个常见误判,是把 502 和 504 一起统称成“服务异常”。虽然它们都和上游有关,但前者更偏代理失败,后者更偏等待超时,定位重点并不完全一样。

第三个常见误判,是把 499 当服务错误。它的核心含义其实是客户端先走了,所以更应该结合用户等待体验、网络质量和前端超时策略来理解。

一个值得自己做的小实验

选一个已有 Nginx 的测试环境,分别访问一个存在的路径、一个不存在的路径,以及一个故意指向慢上游的路径。

1
2
3
curl -I -v https://example.com/
curl -I -v https://example.com/not-found
curl -I -v https://example.com/slow-api

然后尝试判断。

  • 哪个状态码更像是匹配问题。
  • 哪个更像是上游问题。
  • 如果把错误日志一起看,链路解释会不会更清楚。

这个实验非常适合训练“状态码不是答案,而是入口”的思维方式。

小结

Nginx 里的状态码之所以值得系统学习,不是因为它们难记,而是因为它们天然站在请求边界上,最容易把多个层次的问题压缩成一个简单结果。如果你能养成一个习惯:看到状态码先回到代理链路,而不是直接拍脑袋下结论,那么很多 Nginx 问题的排查效率都会立刻提高。