HTTP 的无状态设计:不是缺点,是分布式的前提
很多人说"HTTP 无状态很麻烦,每次都要带 Token"。但问题应该反过来问:为什么 HTTP 故意设计成无状态?
问题的起源
HTTP 诞生于 1991 年,Tim Berners-Lee 的初衷是:用一个简单协议传超文本。
无状态(stateless)的意思是:服务器不记得你上一次请求是什么。
这看起来很蠢——人类明明是有状态的(你在浏览器的操作是连续的)。
为什么要这么设计
答案是:分布式。
如果 HTTP 有状态,意味着这次请求必须回到同一台服务器——因为状态存在那台机器的内存里。
这导致:
- 服务器 A 挂了,所有连在 A 上的用户会话丢失
- 负载均衡器无法随意把请求分给空闲机器
- 扩展性被绑死在"状态"上
无状态的核心取舍:把状态从服务器移到客户端(Cookie)或者第三方(Token/Session 服务器),换来的是整个系统可以无限横向扩展。
补偿机制的本质
Session、Cookie、Token——这些都不是"HTTP 的功能",而是在补偿 HTTP 的无状态设计。
| 机制 | 状态存在哪里 | 代价是什么 |
|---|---|---|
| Cookie | 客户端 | 大小受限(4KB),每次请求都带 |
| Session | 服务器内存 | 服务器之间要同步状态,复杂度高 |
| Token (JWT) | 客户端 + 签名 | Token 无法主动失效,只能等过期 |
认知关键:没有完美方案,只有取舍。选哪个,取决于你的系统愿意为什么付代价。
这个设计教给我们什么
回头看,HTTP 无状态教的是:
分布式系统的第一原则是:不要把状态绑在单点上。
这不是 HTTP 的缺点,这是分布式系统的前提。
后来出现的 RESTful 架构,把"无状态"发扬光大——每个请求都带够信息,服务器不需要记得任何上下文。
验证你有没有想清楚
两个问题:
- 为什么微服务架构下,Session 方案基本被淘汰了?
- JWT 的"无法主动失效"是设计缺陷,还是刻意的选择?它适合什么场景,不适合什么场景?
(答案同样不写在这里——去想清楚,想清楚了才是你的认知。)