HTTP协议与无状态

大家常提起 HTTP 协议是无状态的,其指代的“无状态”是什么?常见的观点有:

  • 无状态代表相同的请求参数总是能返回相同的结果
  • HTTP 本身的设计是无状态的,增加了有状态协议头(Cookie/Session)后变成了有状态协议

对于第一个观点显而易见是错误的,它的表示更倾向于“幂等性”,这往往无法由协议本身保证,还需要服务器进行“有状态”的响应(若服务器不进行状态的持久化,当然无法做到幂等);而第二个观点听起来就靠谱很多,通过 Cookie/Session 进行状态维护从而保证了有状态。但我们可以考虑下 Cookie 或 Session 保证的是谁的状态?一般情况下,它们保证了后端服务器的状态,而非 HTTP 协议的状态。因此对于最初的问题 HTTP 协议的”无状态“,我们是不是应该从协议的本身出发呢?

什么是”无状态“协议

对于”有状态“协议来说,多次请求间往往包含关联,就比如之前提到的服务端依赖 Cookie/Session 进行状态维护来保证关联,但区别在于有状态协议的状态维护应由协议本身来保证,换句话说,“有状态”协议本身存在会话(Session),一般和连接绑定的。比如 TCP 连接,传输双方是需要进行”有状态“交互(双方在三次握手后均进行状态信息的保存),且会话会随着连接断开而结束。反过来说,“无状态”协议本身不存在会话概念,其每个请求无论在哪个连接都是完全独立且正确的(即不会和先前的请求产生关联)

Cookie/Session 所带来的会话不属于协议本身的状态,协议本身也无法应用这些状态。这种状态可以理解为应用程序基于协议实现的”有状态“应用

众所周知 HTTP 协议是利用 TCP 进行数据传输的,那么是否利用 TCP 进行数据传输的协议都是”有状态“协议呢?当然不是,因为它们本身并没有强关联,HTTP 并不是基于 TCP 的协议,它们处于 OSI 的不同层次(HTTP 协议属于应用层协议,TCP 协议属于传输层协议),如果你想的话,也通过命名管道提供 HTTP 服务,因此即使 TCP 协议是“有状态”的,也不能以此判断 HTTP 协议也是“有状态”的

HTTPS 协议本质上是在应用层和传输层中间加入了 SSL 协议(严格来说,HTTPS 协议不算单独的协议),SSL 协议本身也需要通过握手(身份验证)来保持会话,因此 SSL 协议也是”有状态“协议

HTTP 协议是”无状态“协议吗?

分清楚”有状态“/”无状态“协议后,我们可以分析一下 HTTP 协议是否为”无状态“协议:

  • HTTP/1.0 时代每个 TCP 连接只能发送一个请求,因此无法在连接中产生会话的概念,显而易见 HTTP/1.0 协议属于“无状态”协议

  • HTTP/1.1 时代引入了持久连接,即 TCP 连接默认不关闭,可以被多个请求复用。但此时的连接复用仅仅是为了提高传输效率,keep-alive 的默认情况下,它的若干个请求会排队串行化单线程处理,即后面的请求等待前面请求的返回才能获得执行机会,除此之外没有任何优化,因此 HTTP/1.1 协议也属于“无状态”协议

    HTTP/1.1 实际上还支持 pipeline,即连续发送一组没有相互依赖的请求而不必等到上一个请求先结束,但它仍然存在线头阻塞的问题(响应仍然得串行化),使用这项特性需要浏览器支持,且仍然没有对会话的支持

  • HTTP/2.0 时代的报头压缩(HPACK,即客户端和服务器都维护之前看见的标头字段的列表),GOAWAY 帧或流控的特性都标志着会话的诞生,因此 HTTP/2.0 协议属于“有状态”协议

参考

# HTTP

Commentaires

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×