群里甩过来一条报错:unexpected status 502 bad gateway: unknown error, url: http://127.0.0.1:15721/v1/responses。第一眼看过去,502,服务器挂了?但再往下看,URL 是 127.0.0.1,本地回环地址——这根本不是远端服务不可用,而是本机某个代理组件在向上游转发时出了问题,把错误包装成了 502 还给了调用方。
状态码这个东西就是这样:记含义不难,难的是拿到一个数字后知道往哪个方向查。我见过太多人一看到 4xx 就跑去改前端,一看到 5xx 就重启后端,结果折腾半天发现是 Nginx 配置的锅。所以今天想把 HTTP 状态码的含义和排查方向放在一起捋一遍,不按教科书顺序背表,而是按真实排查链路来拆——请求从客户端发出,经过网关、代理,最后落到应用,每一段会产生哪些状态码,拿到之后第一步该看哪里。内容更适合正在写接口的前后端开发、处理线上告警的运维,以及用命令行工具调 API 时被各种 4xx/5xx 搞到崩溃的独立开发者。
1. 先看懂状态码的“分组逻辑”,排查才谈得上方向
1.1 状态码本质上是“服务器对请求处理进度的阶段性裁决”
HTTP 状态码是服务器在收到请求之后,返回给客户端的一个三位数字。这个数字不是随机分配的,百位上的数字决定了它的基本性质:1xx 是信息,2xx 是成功,3xx 是重定向,4xx 是客户端错误,5xx 是服务端错误。
我以前带新人的时候常说一句话:状态码是“服务器对请求处理到哪一步”的裁决快照。比如 200,代表“请求到达了我能处理的最后一环,并且逻辑成功”;404 代表“路由匹配阶段就没找到对应资源”;500 则代表“请求确实进入了业务处理,但代码执行到一半炸了”。同一个请求在不同阶段返回的状态码,直接暴露出问题发生的位置。
1.2 1xx 到 5xx,每一组在真实请求链路里“站在哪一环”
真实请求链路往往是这样的:
客户端 -> CDN / 负载均衡 / 反向代理 -> 应用网关 -> 业务服务 -> 数据库 / 上游第三方接口
状态码组和链路位置有很强的对应关系,用一张表能看得很清楚:
| 状态码范围 | 语义 | 通常发生在链路中的哪一段 | 排查重点 |
|---|---|---|---|
| 1xx | 临时响应,请求还在进行 | 客户端与服务器建立连接阶段 | 极少直接暴露给用户,一般不用管 |
| 2xx | 请求成功 | 业务处理完成 | 看响应体是否符合预期 |
| 3xx | 需要进一步操作 | 路由 / 重定向 / 缓存层 | 看 Location、是否走缓存 |
| 4xx | 请求本身有问题,服务器无法处理 | 接入层校验、鉴权、路由、业务校验 | 拉请求原文,查参数和权限 |
| 5xx | 服务器处理时出错 | 代理转发、应用执行、依赖调用 | 查服务日志,查上游状态 |
这个“站在哪一环”的意识非常关键。比如 403,它在链路里可能由 WAF 返回(接入层拦截),也可能由应用返回(业务权限不足)。如果你只是盯着应用日志查,但真正的 403 是 WAF 拦的,那你永远查不到根因。
1.3 状态码是“结果快照”而不是“完整原因”
这是我在实际排障里体会最深的一点:HTTP 状态码永远只是结果,不是原因。服务器没有义务告诉你“我为什么返回 500”,它只负责告诉你“这次请求的结果是失败,失败的类别属于服务端问题”。
所以排查方向的第一性原则是:拿到一个状态码,不要急着下结论,先把它当成一条线索,下一步去翻请求原文、响应头、响应体、服务日志。状态码告诉你“问题在哪个阶段”,日志和响应体会告诉你“具体原因是什么”。
举个例子,同样一个 400:
- 可能是请求体 JSON 格式坏了,服务端解析不出来;
- 可能是缺少了必填头
Content-Type; - 也可能是请求内容合法,但触发了服务端的某种业务约束。
如果你只记住了“400 = 请求语法错误”,那第三种情况会让你完全摸不着头脑。所以从这一章开始,后面的每一类状态码我都会按“含义 + 产生位置 + 排查方向”三个维度来讲,而不是单纯背表。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 2xx 和 3xx 不代表万事大吉:成功与跳转里那几个坑
2.1 200、201、204、206:同样是成功,语义差别很大
大多数人对 2xx 的态度是“看到 200 就走人”,但实际开发里,2xx 内部也有不少容易踩的细节。
- 200 OK:请求成功,响应体里带结果。这是最常见的,但也是最容易被滥用的——很多后端把业务异常也包装成 HTTP 200,只在响应体里放一个
{"code": 50001, "msg": "余额不足"}。这种设计后面会专门讲,属于“状态码与业务码纠缠”的问题。 - 201 Created:创建成功,通常用于 POST 请求。如果你写接口时发现创建资源后返回 200 也能跑,但更规范的做法是返回 201,并且带上新资源的 Location 头。排查方向没太多坑,主要是别把 200 和 201 混为一谈。
- 204 No Content:请求成功了,但响应体为空。DELETE 请求和部分更新接口喜欢用 204。有个小坑:如果客户端代码里写了“解析响应体为 JSON”,遇到 204 会直接解析失败,但状态码本身是成功的。这类问题往往被当成“接口坏了”来查,实际是客户端没处理空 body。
- 206 Partial Content:范围请求,比如视频拖进度条、文件断点续传。服务器只返回了一部分内容。排查 206 时重点看
Content-Range响应头,判断返回的字节范围对不对。
2.2 301 与 302 的分水岭:永久与临时,直接影响缓存和搜索引擎
3xx 看起来简单,实际上是一个特别容易“埋雷”的区域。
先说两个对网站影响最大的:
- 301 Moved Permanently:永久重定向。搜索引擎会把旧链接的权重迁移到新地址,浏览器会缓存这个跳转。域名从 HTTP 切到 HTTPS、整站改版换路径,用的是 301。
- 302 Found:临时重定向。语义是“这次先跳到别处,下次你还可以用原地址”。登录态失效后跳转到登录页、活动页临时跳转,一般用 30
