《HTTP/2 基础教程》读书笔记

最近几天看了《HTTP/2 基础教程》,现整理如下,以弥补过去知识体系的欠缺。

为方便,HTTP/2 简称 h2,HTTP/1.1(及之前)版本简称 h1。

h2 特性

  • 首部压缩
  • 分帧传输
  • 服务端推送

h2 的出现一定是为了解决 h1 存在的问题。

HTTP 请求、响应分为三部分,其中有 header、body。而 body 是可以通过 Content-Encoding 进行编码压缩的,但头部信息不行,一般请求都会携带不短的 Cookie 等 header,TCP 在慢启动过程中,会经历若干个 RTT,所以如果能对首部进行压缩,会进一步提升性能。

同样是基于请求、响应模型,我们待发送的所有请求都会进入一个队列,通常发送一个请求,等待响应,再发送下一个。如果中间 pending,将会阻塞后面的请求。为此浏览器一般会开启若干个连接,但是对于每个连接实际上依旧会受到队头阻塞的影响。为了打破浏览器对单个域名并发请求的限制,目前一般采用域名拆分。h2 由于分帧传输,请求和响应可以交错甚至多路复用,且 h2 设计思路尽量在一个 TCP/IP socket 上通信。

服务端推送最开始理解类似于“长连接”形式,客户端不用再向以往的方式进行轮询,目前发现当时的想法太局限。以浏览器加载网页为例,h1 时代首先加载 HTML 并解析,然后逐个加载各种静态资源。但这里有个问题就是,如果后端渲染 HTML 导致页面 pending 很长,会导致静态资源加载因此延后。h2 服务端推送可以很巧妙地解决这个问题,通过服务端的配置,在服务端还没有返回 HTML 的同时,可以预先将需要用到的静态资源先推送给客户端。

性能

并非所有请求在任何情况下都会从 h2 受益,而 h2 受丢包影响尤为严重(类比一个 socket 连接和若干条 socket 连接,再遭遇丢包时,受窗口缩小的影响更大)。

但若关注整个页面的加载,受益一定是正向的。

其他

  • 首部压缩不使用 GZIP,是因为有泄漏加密信息的风险。
  • h2 规范并不要求 TLS,但实际验证发现 80 端口通信时,若通信链路上存在代理服务器,错误率会非常高。
  • 过去适用于 h1 的做法将不再适用:

    • 生成精灵图和资源合并/内联。
    • 域名拆分。
    • 禁用cookie的域名。因为首部不会被压缩,导致超过单个 TCP 数据包的 cookie 司空见惯。
Table of Contents