14baf87132b123495c139e581d1356fa
HTTP/2优化与升级

接上回书说,HTTP经历了1.1版本的各种优化,性能有所提高。然而在一些关键指标上还是不尽如人意,比如经典的Head-of-line blocking问题。最开始受不了这些问题的是Google的一帮极客,于是他们自主研发了SPDY协议,此协议后来被很多大的网站如Twitter, Facebook采用。然后HTTP 工作组学习并完善了SPDY,最终形成了新的HTTP/2。 HTTP/2协议完成之后,Google认为SPDY可以功成身退了,于是最终Google Chrome淘汰对SPDY的支持,全面改为采用HTTP/2。

本文将详细讲解HTTP/2的优化工作以及升级HTTP/2的方法。

目录

  1. 二进制分帧
  2. 多路复用
  3. 头部压缩
  4. 服务端推送
  5. 升级到HTTP/2

1. 二进制分帧(Binary Framing)

HTTP/2性能优化的核心和基础是二进制分帧层,它定义了HTTP消息封装和传输的方式。

二进制分帧

二进制分帧

从上图可以看出二进制分帧层位于Socket接口层与更高级的HTTP API层之间,并不改变HTTP的语义、方法、状态码,但对传输的数据重新编码。HTTP/2把HTTP/1.1的Header与Data分别编码成帧了。

在HTTP/2中,数据被划分成3个等级的概念:

流(Stream): 双向的字节流,可以包含一个或多个消息。
消息(Message): 一个完整的帧序列,对应一个逻辑上完整的请求/响应。
帧(Frame): 最小的交换单位,包含一个帧头,其中有个id指向所属的stream。

有了这几个概念,我们来看一下HTTP/2中的数据流过程:

HTTP/2数据流

HTTP/2数据流

可以看出:

  1. 一条TCP连接可以同时包含多个双向Stream。
  2. 每个Stream有一个ID以及可选的优先级信息,可以包含若干个双向Message。
  3. 每个Message是一个逻辑上的HTTP请求/响应消息,包含若干个Frame。
  4. 每个Frame包含一种特定类型的数据,比如HTTP头、消息负载等等。来自不
    同Stream的不同Frame 可以交叉地传输,最后在终端利用Stream ID重新组
    合。

总的来说,HTTP/2协议把数据都打散成许多二进制编码的帧,所有这些帧都可以在同一个TCP连接上交叉多路传输,最后再组装成一个特定流的消息。这种技术是接下来所有优化技术的基础。

2. 多路复用(Multiplexing)

在讲HTTP/1.1的优化中,我们提到了使用多条TCP连接来并发处理请求。然而,这种场景下,每个连接还是只能同时传输一个响应,而且由于FIFO的队列顺序,还存在Head-of-line blocking问题,这无疑是网络延迟的一大弊病。HTTP/2很好地解决了这个问题,这种技术叫多路复用。

多路复用技术利用了上面说的二进制分帧层,做到了完全的请求/响应并发。

HTTP/2多路复用

HTTP/2多路复用

上图一个连接中,客户端在传送一个Stream 5的数据帧,服务端在传送Stream 1和 Stream 3的交叉帧序列,此时相当于一个连接同时有三个Stream在双向传输,nice!!!

因此,有了多路复用技术,我们就不需要HTTP/1.1的Spriting、Concatenation、Domain Sharding技术了,这不仅降低了网络延迟,也提高了网络资源利用率!

看到这里,我们会发现要实现二进制分帧和多路复用技术,一个关键的点就是如何把一个HTTP消息打散成许多帧,然后交叉地在一个连接上传输它们,最后还能在终端准确地重组,这就涉及到Stream的优先级问题了。

Stream 优先级

HTTP/2规定每个Stream可以有一个权重和依赖:

  1. 每个Stream有一个整形值的权重,范围是1~256
  2. 每个Stream依赖一个显式的其他Stream。
top Created with Sketch.