HTTP/2到底有什么魔力

117 阅读7分钟

太久远的协议这里就不涉及了,主要讲一下HTTP/1.1与HTTP/2之间的区别

HTTP/1.1

改进点

针对 HTTP/1.0HTTP/1.1主要进行了以下改进

  • 持久链接
    HTTP/1.0每次请求都新建立TCP连接,请求结束后就关闭该TCP连接。而HTTP/1.1中增加了持久连接,一个TCP连接上可以传输多个HTTP请求,只要浏览器/服务器没有明确断开连接,那么该TCP连接会一直保持。
    • 持久连接在HTTP/1.1中是默认开启的,想要关闭可以在请求头中加上 Connection: close
    • 对于同一域名,浏览器默认允许同时建立6个TCP持久连接
  • 支持虚拟主机
    在HTTP/1.0中,每个域名对应一个IP地址。现在需要在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的域名,这些域名共用一个IP。
    HTTP/1.1的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的Host值做不同的处理。
  • 支持内容动态生成
    HTTP/1.0时,需要在响应头中设置完整的数据大小来让客户端接收数据。而当前很多返回的内容是动态生成的,在传输数据之前并不知道数据大小。
    HTTP/1.1通过引入 Chunk transfer 来解决这个问题:服务器将数据分割成任意个chunk数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。
  1. Cookie、安全机制
    HTTP/1.1还引入了客户端Cookie机制和安全机制

遗留问题

HTTP/1.1核心问题就是对带宽的利用率不高

带宽是指每秒最大能发送或者接收的字节数。把每秒能发送的最大字节数称为上行带宽,每秒能够接收的最大字节数称为下行带宽

而导致这种现象主要有三个原因:

  • TCP慢启动
    慢启动:TCP连接建立之后开始发送数据,刚开始会以一个非常慢的速度去发送,然后慢慢加快,直到发送数据的速度达到一个理想状态。

    慢启动是TCP为了减少网络拥塞的一种策略,本身是合理的。但页面中常用的资源文件本来就不大,如HTML文件、CSS文件和JavaScript文件,通常这些文件在TCP连接建立好之后就要发起请求的;而这个过程是慢启动,所以耗费的时间比正常请求的时间要多。
  • 带宽竞争
    多条TCP连接,当带宽充足时,每条连接发送/接收速度会慢慢增加;在过程中若发现带宽不足,所有TCP连接传输速度又会减慢。
    在这堆TCP连接中,有的是一些关键资源,如JavaScript文件,而有的是图片等普通文件,但它们之间又不能协商让哪些关键资源优先下载,这样就有可能影响关键资源的下载速度了。
  • 队头阻塞
    在HTTP/1.1中使用持久连接时,虽然能共用一个TCP管道,但该管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。阻塞请求的因素有很多,并且都是一些不确定性的因素。如果当前请求被阻塞了5秒,那么后续排队的请求都要延迟等待5秒,在这个等待的过程中,带宽、CPU都被白白浪费了

HTTP/2

改进点

针对 HTTP/1.1HTTP/2主要做了以下改进:

  • 一个域名只有一个TCP
    在HTTP/1.1中,一个域名可以有6个TCP连接,而由于TCP慢启动,这就带来了更多的启动耗时;而在HTTP/2中,一个域名都共用一个TCP连接,这样整个页面资源的下载过程只需要一次慢启动,同时也避免了同一域名下多个TCP连接竞争带宽所带来的问题
  • 多路复用
    HTTP/2采用多路复用机制,实现资源的并行请求,并不需要等其他请求完成后再发下一个请求,服务器也可以随时返回处理好的请求,一定程度上解决了队头阻塞问题
  • 请求的优先级
    HTTP/2可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求。
  • 服务器推送
    HTTP/2允许服务器直接将数据提前推送到浏览器。
    假设用户请求一个HTML页面,服务器知道该HTML页面会引用几个重要的JavaScript文件和CSS文件,那么在接收到HTML请求之后,服务器可以将这些CSS/JavaScript文件一并发送给浏览器。
  • 头部压缩
    HTTP/2对请求头和响应头进行了压缩

如何实现多路复用

HTTP/2在TLS之上也就是TCP之上引入了二进制分帧层

  1. 浏览器发起请求,请求包含请求行、请求头等信息
  2. 二进制分帧层处理数据,对于一个请求,会把请求行、请求头、请求体各自转换为带有请求ID的帧,发送给服务器。
  3. 服务器接收到帧之后,会将所有相同ID的帧合并为一条完整的请求信息
  4. 服务器根据优先级来处理接受到的请求,然后将返回的响应行、响应头和响应体分别发送至二进制分帧层。
  5. 二进制分帧层将这些响应数据各自转换为带有请求ID的帧发送给浏览器。
  6. 浏览器接收到响应帧之后,会根据ID编号将帧的数据提交给对应的请求。

HTTP/2将请求分成一帧一帧的数据去传输,当服务器收到一个优先级高的请求时(比如JS请求),服务器可以暂停之前的请求(比如图片请求)来优先处理关键资源的请求。

遗留问题

HTTP/2遗留问题主要还是在TCP的队头阻塞上

TCP

TCP连接是两台计算机之间的一个虚拟管道,计算机的一端将要传输的数据按顺序放入管道,最终数据会以相同的顺序出现在管道的另外一头

image.png

发送的数据会被拆分为一个个按顺序排列的数据包,这些数据包通过网络传输到了接收端,接收端再按照顺序将这些数据包组合成原始数据,这样就完成了数据传输。

TCP队头阻塞

如果在数据传输的过程中,有一个数据包丢包了,那么整个TCP的连接就会处于暂停状态,需要等待丢失的数据包重新传输过来。

image.png

我们就把在TCP传输过程中,由于单个数据包的丢失而造成的阻塞称为TCP上的队头阻塞

多路复用下的队头阻塞

image.png

在HTTP/2中,同一域名下所有请求是跑在一个TC中的,如果其中任意一个请求出现了丢包的情况,那么就会阻塞该TCP连接中的所有请求。使用HTTP/1.1时,浏览器为每个域名开启了6个TCP连接,如果其中的1个TCP发生了阻塞,那么其他的5个连接依然可以继续传输数据。

TCP建立延时

TCP的握手过程也会影响传输效率