HTTP/2 协议抓包分析
引言
HTTP 协议在我们日常生活中随处可见,不管我们是用电脑、手机、平板,不论用浏览器还是手机 App,背后总有 HTTP 协议在传输着我们所浏览的内容。在 HTTP 协议中,目前应用最广泛的是 HTTP/1.1 协议,但 HTTP/1.1 协议也有其自身的缺点与不足,HTTP/2 协议在 HTTP/1.1 协议的基础上进行了大量的优化,于 2015 年正式发布,目前已经有越来越多的服务支持 HTTP/2 协议。我们大力智能服务端团队对 HTTP/2 协议及原理进行了一些的分析与抓包实战,希望本文能够帮助读者对 HTTP/2 协议基础有一定的了解。
HTTP/1.1 有什么问题?
无法适应互联网页面内容数量与体积的持续增大
在 2010 年之后,随着移动互联网蓬勃发展,网页上资源的数量与体积有着明显的增大,但是浏览器的对同域名下的请求并发度是有限制的,导致网页渲染的延时增大。
例如下图是对某新闻页面的一个抓包结果,可以看到全部加载完毕会有 242 个请求发出,7.2 MB 资源,总完成时间达到了 23.77 秒。
浏览器为什么限制同域名下的请求并发度?
对客户端浏览器而言,过多的并发涉及到端口数量消耗和线程间切换的开销。例如在上图浏览新闻页面中如果不加限制的使用 242 个线程并发请求资源,那么可能有无法忽视的性能开销。
HTTP/1.1 协议中使用了 TCP 协议中的 Keep Alive 属性支持复用现有 TCP 连接,等待服务端的数据返回之后再复用该 TCP 连接继续发送下一个 HTTP 请求,已经比 HTTP/1.0 的每次请求都断开 TCP 连接快很多。
即便客户端不对并发度加以限制,但如果将所有请求一起发给服务器,也很可能会引发服务器的流控策略而被限制。
下图是各个浏览器对并发度的限制:
没有充分利用 TCP 连接资源
TCP 协议是一个全双工的协议,但在 HTTP/1.1 中同一个 TCP 连接下在同一时间只能完成一个 HTTP 请求,即为一问一答的半双工形式,无法最大限度的利用带宽资源。而当前的网络环境大多为长肥网络,即延迟*带宽较大的网络。我们可以想象为两条长而粗的水管,在一个时刻,水管中正在流淌的水就是飞行中的 TCP 报文,理想情况为两条水管分别源源不断的向对方传递水流。
头部与公参数据所占用的巨大比例
HTTP/1.1 的无状态特性带来的巨大 HTTP 头部与公参,每次请求需要携带非常多的头部信息与公参内容,例如下表是对某个 App 应用的一个 HTTP/1.1 请求数据统计,其中的公参与头部数据占了整体请求数据的 90% 以上,这些数据很可能在用户的使用过程中是不会发生变化的,而该现象在很多应用中是较常见的。
可以看到,在 HTTP/1.1 请求过程中,浏览器共使用 6 个并发 TCP 链接请求图片数据(符合上文中的提到 Chrome 并发度为 6 的限制),在很多图片的 HTTP/1.1 请求 Waterfall 中,有很明显的排队等待延时。
而 HTTP/2 中因为使用了多路复用,仅在一个 TCP 连接上传输数据,但其传输速度仍然有明显的提高。
HTTP/2 做了哪些改进?
HTTP/2 连接的建立过程
与 Websocket 协议一样,HTTP/2 协议也是在 HTTP/1.1 协议的基础上通过协议升级进行握手之后才能正式建立连接收发数据。另外,HTTP/2 协议默认使用 TLS 进行数据加密,而 h2c 表明使用明文协议不使用 TLS。