1. 背景
这篇文档会从技术和协议层面来介绍http2。文档起源于2014年4月我在斯德哥尔摩做了一次相关的演讲,在那之后我对演讲内容的细节进行了一些解释和补充,从而写出了这篇文档。
正式版http2规格标准叫做RFC 7540,发布于2015年5月15日:http://www.rfc- editor.org/rfc/rfc7540.txt 如果你有在这篇文章中发现任何我的失误造成的错误或疏漏,请帮我指正。我会在后续版本 中修改。
为了让阅读体验更流畅,在这篇文章中我会使用“http2”来指代这一新协议,但请记住该协议的正式名字是HTTP/2。
2. HTTP的现状
当前,几乎所有互联网上的内容都采用HTTP 1.1作为通信协议。人们在该协议上投入了大量精力,因此基于该协议的基础架构得以日臻完善。得益于此,在现有的HTTP协议之上构建新的方案会比从底层建立新的协议要容易得多。
2.1 HTTP 1.1过于庞大
HTTP刚诞生的时候被看作一个相对简单直观的协议,但时间证明了早期的设计并不尽人意。 于1996年发布的、描述HTTP 1.0规范的RFC 1945只有60页,但仅仅3年之后,描述HTTP1.1规范的RFC 2616就骤增至176页。当我们在IETF小组对该规范进行更新时,更是被拆分成了总页数更多的六个文档(这就是RFC 7230及其文件族的由来与诞生)。总而言之,HTTP1.1包含了太多细节和可选内容,这让它变得过于庞大。
2.2 过多的可选项
HTTP 1.1不仅包含了非常多的细枝末节,也为未来的扩展预留了很多选项。这种事无巨细的风格导致在现有的软件生态中,几乎没有任何实际场景真正实现了协议中提及的所有细节, 甚至要弄清楚“所有细节”到底包括哪些内容都非常困难。这也导致了很多最初不常用的功能在后来的实现中得到很少支持,而有些最初实现了的功能,却又很少被使用。
随着时间推移,当客户端和服务器开始增加对于这些功能的使用时,==互用性== (interoperability)问题就暴露了出来。HTTP管线化(HTTP Pipelining)就是一个非常好的例子。
2.3 未能被充分利用的TCP
HTTP 1.1很难完全使用出TCP协议能提供的所有强大能力。HTTP客户端和浏览器必须要另辟蹊径,去寻找新的解决方案来降低页面载入时间。
与此同时,人们也尝试使用新的协议来替代TCP,但结果证明这也非常困难。无奈之下,我 们只能尝试同时改进TCP协议本身和基于TCP的上层协议。
简单来说,我们可以通过更好的利用TCP来减少传输过程中的中断,并充分挖掘利用那些本 可以用于发送/接受更多数据的时间。下面几段我们将会着重讨论这些问题。
2.4 传输大小和资源数量
如果仔细观察那些最流行的网站首页所需要下载的资源,会发现一个非常明显的趋势。近年 来加载网站首页接受的数据量在逐渐增加,并已经超过了1.9MB。但更重要的是:平均每个页面为了完成渲染需要加载超过100个独立资源。
正如下图所示,这种趋势已经持续了很长一段时间,并且没有减缓的迹象。该图表中绿色直 线展示了传输数据大小的增长,红色直线展示了平均请求资源数量的增长。