状态码怎么分类
状态码是三位数字,首位数字定义类别,后两位没有分类含义。1xx 表示信息,2xx 表示成功,3xx 表示需要进一步动作,4xx 表示请求方有问题,5xx 表示服务端有问题。规范要求客户端按类别处理不认识的码,因此自定义状态码必须落在合法类别之内,语义也要与类别一致。这套分类是监控、告警、重试与缓存策略的共同语言:把语义放错类别,等于告诉整条链路一个错误的事实。
基本信息
| 结构 | 三位数字,首位表示类别 |
|---|---|
| 规范 | RFC 9110 §15;注册表由 IANA 维护 |
| 扩展 | 允许使用未注册的码,但语义必须落在对应类别内 |
| 客户端规则 | 未知码按首位数字的类别处理 |
| 分类含义 | 信息、成功、进一步动作、请求方错误、服务端错误 |
典型使用场景
- 接口设计:为不同结果选择语义准确的状态码,而不是一律返回成功码
- 网关与代理:按类别决定是否重试、是否缓存、是否改写响应
- 监控告警:按类别区分责任方,减少误报与漏报
- 客户端开发:按类别统一处理,避免逐个数码硬编码
- 排障定位:用类别快速判断是调用方问题还是服务方问题
只看状态码与跳转目标
只看状态码与跳转目标
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' https://example.com/ # 打印状态码与跳转目标
curl -sI https://example.com/ | head -3 # 看状态行与关键头部
# 批量检查一组地址的状态码,便于发布后快速巡检
for u in https://example.com/ https://example.com/api/health; do printf '%s ' $u; curl -s -o /dev/null -w '%{http_code}\n' $u; done五类语义与处理要点
| 类别 | 含义 | 处理要点 |
|---|---|---|
| 信息类 | 临时提示,握手或继续发送 | 继续等待最终响应,不要当作结果 |
| 成功类 | 请求已被处理 | 按方法与内容处理结果,注意无内容的情况 |
| 进一步动作类 | 需要客户端再做一步 | 按目标地址与缓存规则跟随,注意方法是否保持 |
| 请求方错误类 | 问题在请求本身 | 修正请求后再试;超时与限流类可退避重试 |
| 服务端错误类 | 问题在服务端或上游 | 幂等请求可退避重试,同时上报与告警 |
客户端处理原则
- 按首位数字分支,未知码落到类别默认行为,而不是直接判定为失败
- 成功类要区分有无响应体,无内容时不要解析内容
- 进一步动作类要限制跟随次数,避免跳转环导致请求打转
- 请求方错误类要区分可重试与不可重试,避免无意义重试放大日志
- 服务端错误类对非幂等请求不要自动重试,除非有幂等保障
四个常见误用
- 把业务错误塞进成功码,监控看不到真实失败率
- 自定义码落在错误类别,例如用成功类表示客户端中断
- 用请求方错误类表达服务端内部异常,把责任推给了调用方
- 同一语义在不同接口用不同码,调用方无法统一处理
责任方怎么快速判断
| 观察 | 结论 |
|---|---|
| 同一请求参数换环境仍失败 | 多半是请求构造问题 |
| 同一接口所有请求都失败 | 多半是服务端或依赖故障 |
| 只有特定来源或客户端失败 | 多半是策略限制或客户端实现差异 |
| 失败集中在发布或扩容时间点 | 多半是变更引入 |
类别是契约,具体码是细节:调用方只依赖类别也能正确工作,这是规范刻意设计的兼容性。反过来说,如果你自定义的码连类别语义都不对,任何按规范实现的客户端都会做出错误反应。
把业务错误码与状态码两层体系混着用会让自动化监控无法区分责任方:同一批接口里既有靠状态码判断的、又有靠响应体字段判断的,告警阈值与重试策略都会失真。