📄 一句话概括
状态码是三位数字,第一位定责任方:4 开头是你的锅,5 开头是我的锅。 后两位只在本家族内有意义。
📝 本节和前面几节的关系
前三章拆完了报文。 从这一节起看响应的第一行——那三个数字是运维排查的第一手线索,也是监控告警的唯一依据。
一、五个家族,一句话分工
| 家族 | 含义 | 谁该动手 |
|---|---|---|
| 1XX | 信息,请求已收到,继续 | 客户端等 |
| 2XX | 成功 | 没人需要动手 |
| 3XX | 重定向,还要再走一步 | 客户端跟着走 |
| 4XX | 客户端错,改请求才有用 | 客户端 |
| 5XX | 服务端错,改请求没用 | 服务端 |
| 这条分工比记住具体哪个码重要得多。 | ||
| 看到 4XX 先去查请求(参数、认证、路径), | ||
| 看到 5XX 先去查服务端日志——方向对了,一半时间就省下了。 | ||
| 后两位没有跨家族规律。 | ||
| 不要以为「400 和 500 差不多」——一个是语法错,一个是内部崩溃,处理方式完全相反。 |
二、原因短语是可以扔掉的
HTTP/1.1 200 OK 里的 OK 叫原因短语(reason-phrase),纯粹给人看,程序只认那个数字。
你可以写 200 一切正常,甚至留空,客户端照样工作。HTTP/2 干脆把它删了——状态行只有版本和数字。
这也是排查时的一个提醒:日志里看到奇怪的原因短语,说明中间某个设备改过它,
而那个设备可能也改了别的东西。
三、1XX 几乎见不到
100 Continue 是唯一还有存在感的:客户端要发大正文时,先发首部问一句「你收吗」,
服务端回 100 再发正文,避免白传。
101 Switching Protocols 用在 WebSocket 握手:服务端同意把这条连接升级成别的协议(9.3 节)。
这两个都出现在「请求还没结束」的阶段,抓包里夹在中间,不熟悉的人常常当成异常。
四、动手 Demo:把常见状态码按家族数一遍
把 26 个常见状态码按「百位」分组统计,看每个家族有多少个、分别是哪些。数字全部由代码算。
codes = [(100, u'Continue'), (200, u'OK'), (301, u'Moved Permanently'),
(404, u'Not Found'), (500, u'Internal Server Error'), ...]
fam = {}
for c, name in codes:
fam.setdefault(c // 100, []).append((c, name))
实跑输出:
--------------------------------------------------------------------
状态码是一位数分家族的三位数字
--------------------------------------------------------------------
统计的码总数 26 个
1XX 信息(请求已收到,继续) 2 个
2XX 成功 4 个
3XX 重定向(还要再走一步) 6 个
4XX 客户端错(改请求才有用) 9 个
5XX 服务端错(改请求也没用) 5 个
1XX:100、101
2XX:200、201、204、206
3XX:301、302、303、304、307、308
4XX:400、401、403、404、405、408、413、416、429
5XX:500、501、502、503、504
第一位的作用 判断责任方:4 是客户端的锅,5 是服务端的锅
后两位 只在该家族内有意义,没有跨家族规律
原因短语 纯给人看,程序只认数字(HTTP/2 已删除)
记住「第一位定责任方」这一条,排查就有一半方向了:
看到 4XX 先查自己的请求,看到 5XX 先查服务端日志。
统计的码总数 26 个,分成 2/4/6/9/5 五组。4XX 最多,因为客户端能犯的错花样最多。
第一位的作用 判断责任方——这一行是整节的结论。把它写进监控规则的备注里,值班的人会感谢你。
原因短语 纯给人看,程序只认数字(HTTP/2 已删除)。
这一条在写客户端时很关键:别按短语判断,一定按码判断。
30 秒实验
- 把 418(I'm a teapot)加进列表,看它落在哪个家族。
- 列出你自己项目里用到的状态码,看看有没有「全用 200」的接口。
- 查一下 499 这个码——它不在任何标准里,是 Nginx 自己加的。
常见误区
- 「状态码越具体越好」——用错家族比用错具体码更糟。业务失败回 200 是最大的坑。
- 「原因短语可以当判断依据」——程序只认数字,短语随便改。
- 「所有错误都应该回 500」——400 和 500 的责任方完全不同,混用会让排查方向全错。
自测三问(点开对答案)
1. 状态码第一位的作用是什么? —— 判断责任方:4XX 客户端、5XX 服务端、3XX 要再走一步、2XX 成功。 2. 原因短语能用来做判断吗? —— 不能。程序只认数字,短语是纯文本说明,HTTP/2 已经把它删了。 3. 1XX 出现在什么时候? —— 请求还没结束时,比如 `100 Continue` 表示「可以继续发正文」。家族分清了。接下来逐个看:先看最熟悉的 2XX。
- ☐ (本节完,下一节 4.2.1 200 OK)