HTTP/2 主要特点与优缺点


简介
HTTP/2 主要目的是提高网页性能,最近几年比较火,将其单独抽成一块讲。2015 年,HTTP/2 发布。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。
目前还有不少服务还是 HTTP/1.1,NodeJS 也是从 v10 才将 http2 转正。Express5.x 才开始支持 http/2。

可以打开谷歌首页看看,基本上都是 http/2 协议,简写成 h2

HTTPS 是 HTTP/2 的必要条件。
可以用 Chrome 插件可以用来检测 HTTP/2:HTTP/2 and SPDY indicator。它会给浏览器添加了一个闪电标记:

- 蓝色闪电,表示这个网页是运行在 HTTP/2 上
- 红色闪电表示网页运行在 SPDY 上(spdy 和 h2 的关系和参考这篇文章:HTTP 协议入门)
- 灰色闪电则表示着这个网页既不是运行于 HTTP/2,也不是运行于 SPDY
一个 TCP 连接

图:HTTP/1.1与HTTP/2数据传输对比图
由上图可以看出,HTTP/1.1 中同一个 TCP 连接里面,上一个响应发送完了,服务器才能发送下一个。而 HTTP/2 采用多路复用(后面介绍)允许单一的 TCP 连接同时发起多重的请求响应,比如 GET style.css 和 GET script.js 差不多就是同时发送的。
Chrome 在 HTTP/1.1 中会建立 6 个 TCP ,在 HTTP/2 中同域名下会建立 1 个 TCP 。
二进制传输
HTTP/1.1 头信息是文本(ASCII 编码),数据体可以是文本,也可以是二进制。这样就会引发一个问题:所有的数据必须按顺序传输,比如需要传输:helloworld,只能从 h 到 d 一个一个的传输,不能并行传输,因为接收端并不知道这些字符的顺序,所以并行传输在 HTTP/1.1 是不能实现的。

HTTP/2 则是一个彻底的二进制协议,二进制协议解析起来更高效。头信息和数据体都是二进制,并且统称为"帧"(frame):
- 头信息帧(HEADERS frame):存放头数据
- 数据帧(DATA frame):存放实体数据

它把 TCP 协议的部分特性挪到了应用层,把原来的 "Header+Body" 的消息"打散"为数个小片的二进制帧,HTTP/2 数据分帧后 "Header+Body" 的报文结构就完全消失了,协议看到的只是一个个的"碎片"。这样发送的时候先后顺序无所谓了,可以根据帧号将它们重新排列起来。这样同一个 TCP 连接里面同时发生多个请求响应。


帧对数据进行顺序标识,如下图所示,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据,这就是流所做的事情。

二进制的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多,且解析起来更高效。。
多路复用(Multiplexing)
解决两大问题
在 HTTP/2 中引入了多路复用的技术,解决了 keep-alive 的性能问题。主要包括: