深入浅出:HTTP/2

HTTP/2 的目的就是通过支持请求与响应的多路复用来减少延迟,通过压缩HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。为达成这些目标,HTTP/2 还会给我们带来大量其他协议层面的辅助实现,比如新的流量控制、错误处理和更新机制。上述几种机制虽然不是全部,但却是最重要的,所有Web开发者都应该理解并在自己的应用中利用它们。

HTTP/2 不会改动HTTP的语义。HTTP方法、状态码、URI及首部字段,等等这些核心概念一如往常。但是,HTTP/2 修改了格式化数据(分帧)的方式,以及客户端与服务器间传输这些数据的方式。这两点统帅全局,通过新的组帧机制向我们的应用隐藏了所有复杂性。换句话说,所有原来的应用都可以不必修改而在新协议运行。这当然是好事。

下面我们就来详细介绍一下这些新的机制。

历史及其与SPDY的渊源

SPDY是谷歌开发的一个实验性协议,于2009年年中发布,其主要目标是通过解决HTTP 1.1中广为人知的一些性能限制,来减少网页的加载延迟。大致上,这个项目设定的目标如下:

页面加载时间(PLT,Page Load Time)降低50%;

无需网站作者修改任何内容;

把部署复杂性降至最低,无需变更网络基础设施;

与开源社区合作开发这个新协议;

收集真实性能数据,验证这个实验性协议是否有效。

2012年,这个新的实验性协议得到了Chrome、Firefox和Opera的支持,很多大型网站(如谷歌、Twitter、Facebook)都对兼容客户端提供SPDY会话。换句话说,SPDY在被行业采用并证明能够大幅提升性能之后,已经具备了成为一个标准的条件。最终,HTTP-WG(HTTP Working Group)在2012年初把HTTP/2 提到了议事日程,吸取SPDY的经验教训,并在此基础上制定官方标准。

走向HTTP/2

从那时起,SPDY 已经经过了很多变化和改进,而且在 HTTP/2 官方标准公布之前,还将有很多变化和改进。在此,有必要回顾一下HTTP/2 宣言草稿,因为这份宣言明确了该协议的范围和关键设计要求:

HTTP/2 应该满足如下条件:

相对于使用TCP的HTTP 1.1,用户在大多数情况下的感知延迟要有实质上、可度量的改进;

解决HTTP中的“队首阻塞”问题;

并行操作无需与服务器建立多个连接,从而改进TCP的利用率,特别是拥塞控制方面;

保持HTTP 1.1的语义,利用现有文档,包括(但不限于)HTTP方法、状态码、URI,以及首部字段;

明确规定HTTP/2 如何与HTTP 1.x互操作,特别是在中间介质上;

明确指出所有新的可扩展机制以及适当的扩展策略;

HTTP/2 特征 二进制分帧层

HTTP/2 性能增强的核心,全在于新增的二进制分帧层(如下图所示),它定义了如何封装HTTP消息并在客户端与服务器之间传输。

深入浅出:HTTP/2

这里所谓的“层”,指的是位于套接字接口与应用可见的高层HTTP API之间的一个新机制:HTTP的语义,包括各种动词、方法、首部,都不受影响,不同的是传输期间对它们的编码方式变了。HTTP 1.x以换行符作为纯文本的分隔符,而HTTP/2 将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。

这样一来,客户端和服务器为了相互理解,必须都使用新的二进制编码机制:HTTP 1.x客户端无法理解只支持HTTP/2 的服务器,反之亦然。不过不要紧,现有的应用不必担心这些变化,因为客户端和服务器会替它们完成必要的分帧工作。

首部压缩

HTTP的每一次通信都会携带一组首部,用于描述传输的资源及其属性。在HTTP 1.x中,这些元数据都是以纯文本形式发送的,通常会给每个请求增加500~800字节的负荷。如果算上HTTP cookie,增加的负荷通常会达到上千字节。为减少这些开销并提升性能,HTTP/2会用 “HPACK” 算法来压缩头部数据。

“HPACK”算法是专门为压缩 HTTP 头部定制的算法,与 gzip、zlib 等压缩算法不同,它是一个“有状态”的算法,需要客户端和服务器各自维护一份“索引表”,也可以说是“字典”(这有点类似 brotli),压缩和解压缩就是查表和更新表的操作。

HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;

首部表在HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新;

每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssjxp.html