目录
HTTP/HTTPS 被设计为无状态协议 ,主要是出于简单性、可伸缩性和可靠性的考虑。
"无状态"意味着每个HTTP请求都是完全独立的。服务器不会在处理完一个请求后,保留任何关于该客户端的"状态"或"记忆"。下一个请求到来时,服务器会将其视为一个全新的、毫不相关的请求。
为什么选择无状态?
一、简单性
-
这是最根本的原因。无状态协议使得服务器逻辑变得非常简单。服务器只需要解析请求、返回响应,然后就可以立刻"忘记"这个客户端。它不需要为成千上万的并发用户维护复杂的会话信息(比如他们在看哪个页面、购物车里有什么东西)。
-
这种简单性降低了服务器的实现复杂度和资源消耗(CPU和内存)。
二、可伸缩性
-
这是无状态架构带来的最大好处。由于服务器不保存客户端状态,任何一个服务器实例都可以处理来自任何客户端的任何一个请求。
-
这使得水平扩展 变得极其容易。当用户量激增时,你只需要在负载均衡器后面简单地添加更多的服务器即可。用户的第一个请求可能被发到服务器A,第二个请求可能被发到服务器B,这完全没有问题,因为服务器B不需要知道用户在服务器A上做过什么。
-
如果服务器有状态,用户A的会话数据只存在于服务器A上,那么负载均衡器必须确保用户A的所有后续请求都被粘性地定向到服务器A。如果服务器A宕机,用户A的整个会话就丢失了,体验非常糟糕。
三、可靠性
-
服务器崩溃后,恢复起来更简单。因为它没有需要恢复的复杂会话状态,重启后就能立即投入工作。
-
无状态设计也简化了故障排查,因为每个请求的上下文都是自包含的。
四、符合早期Web的初衷
- HTTP最初是为了让学术界共享静态文本文档而设计的。你请求一个文档,服务器给你,交互就结束了。这种"一问一答"的模式天然适合无状态设计。
无状态带来的问题与解决方案
现代Web应用(如电商、社交网络、网银)是高度有状态的。你需要登录、往购物车加商品、个性化推荐等。那么,我们是如何在无状态的HTTP之上构建出有状态的Web体验的呢
:通过在客户端和服务器之间来回传递"状态信息"来模拟出"有状态"。
主要的机制有:
-
Cookie
-
Session
-
Tokens(如JWT)
-
URL重写与隐藏表单域
在一些简单或古老的场景中,状态信息会被直接嵌入到URL的查询字符串中(如 ?sessionid=abc123),或者作为隐藏字段放在HTML表单里。这些信息会随着下一次请求被发送回服务器。
关于HTTPS
HTTPS = HTTP + SSL/TLS加密。无状态是HTTP协议的特性,与是否加密无关。 HTTPS同样是无状态的。SSL/TLS层负责加密通信通道,但它并不关心上层HTTP协议的无状态本质。
实际上,为了建立加密连接而进行的"SSL/TLS握手"过程本身是有状态的,双方需要协商密钥并维护加密会话。但这个状态是存在于TCP/SSL层的,与应用层的HTTP无状态是两回事。
比喻
无状态的HTTP想象成一个记忆力极差的餐厅服务员:
优点:他非常高效,点完一桌菜立刻去服务下一桌,餐厅可以轻松雇佣很多这样的服务员,生意可以做得很大(可伸缩性)。
缺点:他记不住你是谁。你让他加一杯饮料,他走过来时会一脸茫然地看着你,不知道你刚才点了什么。
解决方案:你给他一张存根(Cookie/Session ID/Token),上面写着你的桌号。每次你叫他,都把存根给他看。他拿着存根去后台的中央记录本(数据库/缓存)查一下,就知道你点了什么菜,需要加什么饮料了。