很多线上排障都是从一个状态码开始的,比如 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 | curl -I -v https://example.com/ |
然后尝试判断。
- 哪个状态码更像是匹配问题。
- 哪个更像是上游问题。
- 如果把错误日志一起看,链路解释会不会更清楚。
这个实验非常适合训练“状态码不是答案,而是入口”的思维方式。
小结
Nginx 里的状态码之所以值得系统学习,不是因为它们难记,而是因为它们天然站在请求边界上,最容易把多个层次的问题压缩成一个简单结果。如果你能养成一个习惯:看到状态码先回到代理链路,而不是直接拍脑袋下结论,那么很多 Nginx 问题的排查效率都会立刻提高。