cat
Published on

HTTP各版本演进及主要特性对比

这篇文章写了啥?

本文将详细介绍HTTP协议从1.0到2.0的演进过程,重点对比分析各版本的主要特性及其解决的具体问题。

HTTP1.0

无状态协议

HTTP1.0是一个无状态协议,服务器不会保存客户端的任何信息。这种设计使得服务器可以更简单地处理请求,但也带来了一些限制。

无法复用连接

HTTP1.0为每个请求都会新建一个TCP连接,这种设计带来以下问题:

  1. 连接的建立和销毁都会占用服务器和客户端的资源,造成内存资源的浪费
  2. 每次建立TCP连接都需要经过三次握手,增加了响应时间
  3. TCP协议的「慢启动」特性无法被充分利用,影响传输效率

TCP慢启动是一种拥塞控制机制,新建立的连接会从较小的窗口大小开始传输,逐步增加到最优值。频繁的建立新连接会导致传输效率始终处于次优状态。

HTTP1.1

长连接

为了解决HTTP1.0的问题,HTTP1.1默认开启长连接,即让同一个TCP连接服务于多个请求-响应。 在这种情况下,多次请求响应可以共享同一个TCP连接,这不仅减少了TCP的握手和挥手时间,同时可以充分利用TCP「慢启动」的特点,有效的利用带宽。当需要的时候,任何一方都可以关闭TCP连接

队头阻塞

HTTP1.1允许在响应到达之前发送下一个请求,这样可以大幅缩减带宽限制时间,但这样做会存在队头阻塞的问题。 由于多个请求使用的是同一个TCP连接,服务器必须按照请求到达的顺序进行响应,因为服务器需要考虑竟态问题。导致了一些后发出的请求,无法在处理完成后响应,产生了等待的时间,而这段时间的带宽可能是空闲的,这就造成了带宽的浪费。队头阻塞虽然发生在服务器,但这个问题的根源是客户端无法知晓服务器的响应是针对哪个请求的。

我们有以下几种优化手段

1.通过减少文件数量,从而减少队头阻塞的几率,如雪碧图

2.通过开辟多个TCP连接,实现真正的、有缺陷的并行传输

浏览器会根据情况,为打开的页面自动开启TCP连接,对于同一个域名的连接最多6个。如果要突破这个限制,就需要把资源放到不同的域中。

HTTP2.0

二进制分帧

HTTP2.0可以允许以更小的单元传输数据,每个传输单元称之为帧,而每一个请求或响应的完整数据称之为流,每个流有自己的编号,每个帧会记录所属的流。 每个帧都带了一个头部,记录了流的ID,这样做就能够准确的知道这一帧数据是属于哪个流的。

这样就真正的解决了共享TCP连接时的队头阻塞问题,实现了真正的多路复用

多路复用

基于二进制分帧层设计,HTTP2.0实现了真正的多路复用:

  1. 同一个域名只需要建立一个TCP连接
  2. 多个请求可以并行传输,不会互相阻塞

我对多路复用的理解:

使用一套TCP连接 互不干扰的完成数据的传递

头部压缩

HTTP2.0之前,所有的消息头都是以字符的形式完整传输的。可实际上,大部分头部信息都有很多的重复。为了解决这一问题,HTTP2.0使用头部压缩来减少消息头的体积。

服务器推

HTTP2.0允许在客户端没有主动请求的情况下,服务器预先把资源推送给客户端

当客户端后续需要请求该资源时,则自动从之前推送的资源中寻找