核心答案:API 报错按「状态码 → 责任方」分流:4xx 是客户端问题(401 未认证、403 无权限、429 请求过频),5xx 是服务端问题(502 上游故障、503 过载、504 超时)。JWT 不过期先本地解码看 exp 字段;SLA 99.9% 对应每月 43.8 分钟停机预算。
状态码决策树
拿到错误码先问三个问题:
- 4 开头? → 问题在请求方:参数、认证、权限、频率
- 5 开头? → 问题在服务方:重试之前先看对方状态页
- 没有状态码(CORS/网络错误)? → 请求根本没到达或响应被浏览器拦截——查控制台详情,不是接口本身坏了
高频状态码速查表
| 状态码 | 含义 | 第一动作 |
|---|---|---|
| 400 | 请求格式错误 | 对文档逐字段核参数类型 |
| 401 | 未认证 | 查 token 是否过期/未带 |
| 403 | 无权限 | 查账号权限/scope/IP 白名单 |
| 404 | 路径不存在 | 核 URL 拼写与版本前缀 |
| 429 | 请求过频 | 指数退避,看 Retry-After |
| 500 | 服务端异常 | 报障,附 trace id |
| 502 | 网关上游故障 | 查上游服务存活 |
| 504 | 网关超时 | 查慢查询/超时配置 |
完整 26 个状态码可用 [HTTP 状态码速查](/c/dev/http-status) 搜索定位。
JWT 三段结构与过期检查
JWT 格式:xxxxx.yyyyy.zzzzz,三段均为 Base64URL 编码:
- header:算法与类型(
{"alg":"HS256","typ":"JWT"}) - payload:用户数据 + 时间声明——
exp过期时间、iat签发时间、nbf生效时间(均为 Unix 秒) - signature:签名,服务端用密钥对前两段签名
本地排障:把 token 粘进 [JWT 解码器](/c/dev/jwt),header/payload 直接可读,exp 自动换算本地时间并显示剩余有效期。注意:解码 ≠ 验签——任何人都能解码 payload,敏感数据永远不要放进 JWT。
SLA 停机预算对照表
| SLA | 年停机 | 月停机 | 典型场景 |
|---|---|---|---|
| 99% | 3.65 天 | 7.3 小时 | 内部工具 |
| 99.9% | 8.77 小时 | 43.8 分钟 | 一般商用 |
| 99.95% | 4.38 小时 | 21.9 分钟 | 电商主站 |
| 99.99% | 52.6 分钟 | 4.38 分钟 | 支付核心 |
| 99.999% | 5.26 分钟 | 26.3 秒 | 运营商级 |
每加一个 9,停机预算缩 10 倍,架构成本指数上升——多活、自动故障转移是 99.99% 的入场券。
实例:curl 502 排查五步走
现象:curl https://api.example.com/pay 返回 502 Bad Gateway。
- 换网络重试(排除本地链路)→ 仍 502
- 查服务状态页/群公告 → 无公告
curl -v看响应头via/server→ 是 nginx 网关发出,说明网关活着、上游应用挂了- 登录网关机
ss -lptn查上游端口 → 无监听,应用进程崩溃 - 看应用日志末行 → OOM killed → 重启+加内存限制+告警
实例:JWT 401 定位
现象:前端调 /api/orders 返回 401。
- 解码 token →
exp: 1785964800(今天 12:00),当前 14:00 → 过期 2 小时 - 但前端有 refresh 逻辑为何没触发?→ refresh 接口也 401
- 解码 refresh token → 正常 → 查请求头 → Authorization 拼成了
Bearer少了空格后的 token(拼接 bug)
工具链:JWT 解码器看时间 → [URL 解析器](/c/dev/url-parser) 核 query 参数是否带错 → 状态码速查确认 401 vs 403 语义。
常见误区
- 401 当 403 用:401=「你是谁」(没带/过期凭证),403=「知道你是谁,但你没权限」。混用会让前端误判要不要跳登录。
- 重试 5xx 不设上限:雪崩场景下无退避重试等于 DDoS 自己。正确姿势:指数退避 + 抖动 + 熔断。
- JWT 里放手机号/身份证:payload 只是 Base64 编码,谁都能解码——JWT 不是加密容器。
- 「四个 9 随便上」:99.99% 意味着全年只能挂 52 分钟,一次手滑重启就可能花光全年预算;没有多活架构不要承诺。