4xx 和 5xx 怎么快速分流排查

工具相关 ·

线上接口开始报错,运维群里同时有人贴出 502 和 401 两种截图,讨论立刻变得混乱。其实在打开日志平台之前,有一个动作只要两秒钟,却能把排查范围直接砍掉一半——看状态码的第一位数字。

第一位数字是责任分界线

HTTP 状态码固定三位,第一位表示响应的类别。这不是随意的编号规则,而是一套责任划分:1xx 表示服务端已收到、还在处理,2xx 表示请求成功,3xx 表示资源换了位置,4xx 表示调用方的请求有问题,5xx 表示服务端自己出了故障。

这条线的价值在于,4xx 和 5xx 的修复责任方完全不同。看到 4xx,需要检查的是请求参数、请求头、URL 拼写、请求体格式和访问权限,这些都在调用方手里,不必等服务端排期;看到 5xx,要看的是服务端日志、依赖服务状态、数据库连接数、磁盘空间和超时配置,调用方通常只能重试或等待。

把这两类混在一起讨论,最常见的后果是对着 5xx 反复修改自己的请求参数,改了很久毫无效果,因为问题根本不在请求里。

4xx 内部还要再分两层

确定是调用方问题之后,4xx 内部仍然需要细分,因为处理动作差别很大。

第一层是「请求能不能被理解」。400 表示报文格式错误,比如 JSON 少了一个引号;404 是路径不存在;405 是方法不对,用 GET 去调只接受 POST 的接口;415 是 Content-Type 不被支持,典型场景是把表单数据当成 JSON 提交。这一类的共同点是请求还没进入业务逻辑就被拒绝,改请求即可。

第二层是「能被理解,但不能被执行」。401 和 403 是这里最容易混淆的一对:401 是「你没告诉我你是谁」,即未认证,通常意味着凭据缺失、过期或签名不对;403 是「我知道你是谁,但你不能这么做」,即已认证但无权限。判断方法很直接——带上正确的凭据后如果仍然返回 401,问题在凭据本身;如果变成 403,问题才在权限配置。

还有几个 4xx 与请求体积有关。413 表示请求体过大,Nginx 的 client_max_body_size 默认只有 1MB,上传稍大的文件就会撞上,需要同时调整 Nginx 与 PHP 的 upload_max_filesize、post_max_size。431 表示请求头过大,通常是 Cookie 堆积或 JWT 过长,可以清理冗余 Cookie、缩短 Token,或调大 large_client_header_buffers。

429 是限流信号,它不表示请求有错,而是「你发得太快了」。正确做法是读取响应头里的 Retry-After 按指定时间退避,并配合指数退避与随机抖动,而不是立刻原样重试——那只会让限流更严重。

5xx 的关键是分清「有没有响应」

服务端错误的排查方向,取决于上游到底给没给出响应。

502 Bad Gateway 是代理收到了上游的无效响应,通常意味着后端进程崩溃、没启动,或者端口配置错了。504 Gateway Timeout 是代理等待上游响应超时,后端进程还活着,只是处理太慢。一句话概括:502 看「有没有响应」,504 看「响应得够不够快」。前者去查进程和端口,后者去查慢查询、外部依赖调用和超时阈值。

500 是业务代码抛出了未捕获的异常,一定要看应用日志里的堆栈。503 表示服务暂时不可用,常见于发布重启、连接池耗尽或主动降级。

需要提醒的是,5xx 不一定都是应用返回的,代理层自己也会产生这些码。看到 502 时先确认请求究竟打到了哪一层,再决定去翻 Nginx 日志还是应用日志。

3xx 和 200 也不能掉以轻心

有一类问题状态码完全正常,结果却不对。请求被 3xx 重定向到了一个不再返回数据的旧地址,客户端跟随过去后拿到空结果,此时状态码是 200,看起来一切正常。所以遇到「接口返回空数据」时,先确认实际请求的最终地址是不是预期的那个。

同样的道理,200 只表示 HTTP 层成功,不代表业务成功。很多系统把业务错误码放在响应体里,HTTP 状态码仍是 200,排查时必须看响应体结构、分页参数和后端的过滤条件。

排查清单

  • 第一步看首位数字:4xx 查请求,5xx 查服务端,3xx 先确认是否符合预期
  • 4xx 先分「格式被拒」还是「权限不足」,401 与 403 用「换正确凭据后码是否变化」判定
  • 5xx 先分「有没有响应」:502 查进程与端口,504 查慢调用与超时
  • 遇到 413、431 先量体积和头部大小,别急着改业务代码
  • 遇到 429 严格按 Retry-After 退避,并加指数退避与抖动
  • 状态码正常但结果异常时,检查是否发生了重定向,以及响应体里的业务错误码
阅读 13