2015 年 2 月,互联网工程任务组(ietf)批准了 http/2 标准提案,1999 年 http/1.1 正式标准化 ,而 http/2 是自那时以来的首个重大升级。http/2 的主要目标是与 http/1.1 完全语义兼容的基础上,进一步减少网络延迟。换句话说,http/2 要在不破坏原有 web 体系的基础上使它变得更快。

<a target="_blank"></a>
自 2009 年底以来,google 一直在开发一个实验性的协议,这个神秘的协议名叫 spdy(读作 speedy)。spdy 并不是一个首字母缩略词,其实,它是 google 注册的一个商标,http/2 正是起源于这个 spdy 实验。事实上,后来有许多曾经参与 spdy 项目的核心开发者同样也加入到 http/2 的开发中去。在 2015 年 2 月,google正式宣布停止支持 spdy 计划,全力支持 http/2 的开发,预计在 2016 年前实现全部功能。
自 1999 年以来,http/1.1 默默地为我们服务了十几年,它是在当时那样的计算机和网络应用场景下被设计出来的。我不说你也知道,http 早就应该升级了。为了便于描述 http/1 是如何工作的,我在下面放了几张图解。根据序号的顺序你就会看到,从客户端开始(很可能是一个web浏览器)与右方的服务器建立一个 http/1 的连接。
(2) 客户端/浏览器随后发送一个 get 请求(http 方法)获取 <code>index.html</code> 页面。 (3) 服务器响应客户端请求的资源。 (4-7) 在我们这个简单的示例中,这个不断进行的 请求-响应循环过程 持续地获取样式表和脚本来完善整个 html 文档。 (8) 最终,这个 http/1 连接断开了。
http/1 请求/响应 循环
如你所见,客户端/浏览器 花费大量的时间等待每一个资源被响应。因为 http/1 不能在同一个连接上进行并发请求,浏览器通常需要开启多个连接来加速请求资源的过程。
即使开启多个连接能有效提高资源的加载速度,但是从计算机网络的角度来看,开启每一个连接的代价都很高。所以,现代浏览器通常都有最多 6-8 个 http/1.1 连接的限制,许多网站现在需要加载 80多个或者更多的资源,这些连接限制逐渐成为了整个 web 系统的性能瓶颈。
多路复用允许同时通过单一的 http/2 连接发起多重的请求-响应消息,为了向你们量化展示一个 http/2 连接到底快多少,我准备了一套并排的图对比 http/2 与 http/1 的性能,在这个简单的示例中只请求 3 个资源,从 web 页面开始渲染到加载结束,http/2 比 http/1 节省不少时间。
推而广之,当 80 个资源复合请求时,与 http/1.1 相比,很明显通过单一连接进行传递的 http/2 更高效!
http/1 与 http/2 作对比
除了多路复用,http/2 还是二进制的,与 http/1 这样的文本协议相比,二进制协议解析起来更加高效。很显然,二进制的协议更适合在线路进行传输,并且更不容易出错。
http/2 同时也减少了压缩头部的开销,这些在 http/1 里都没有实现。
在 http/2 中,服务器推送是指在客户端请求之前发送数据的机制。如果一个请求是由你的主页发起的,服务器很可能响应主页内容、logo以及样式表,因为它知道客户端会用到这些东西。这相当于在一个 html 文档内集合了所有的资源,不过与之相比,服务器推送有一个很大的优势:可以缓存!
当然这同时也是它的一个缺点,如果客户端已经缓存了数据,此时会产生不必要的冗余。这也是为什么我推荐服务器提示(server hints)的原因。
服务器提示可以先于客户端检测到将要请求的资源,提前通知客户端,服务器不发送所有资源的实体,它只发送资源的 url。客户端接到提示后进一步验证之前的缓存,如果发现需要这些资源,则正式发起请求。服务器提示对 http/2 来说兴许不是最新的,但非常值得在这里顺便一提,因为它没有上文提到的服务器推送冗余的缺点。
服务器提示是通过 http link header 和与已实现的 link prefetching 语义重叠的部分来实现的。举个例子,一个 http link header 看起来是这样的:
如果 html 文档的 head 标签中有一个 <code>prefetch</code> link标签,不需要在服务端有额外的实现,举个例子:
预加载关联用于声明一个资源和它的 fetch 属性,这个规范通过额外的处理策略扩展了功能,有效地获取在下一个导航可能需要请求的资源,举个例子
一些浏览器中,<code>loadpolicy="next inert"</code> 等同于 <code>rel=prefetch</code> 这样的实现,<code>loadpolicy</code> 属性的 <code>next</code> 值在语义上与 <code>rel=prerender</code> 相同,这个规范对预获取和预渲染的功能进行了标准化,并且给他们扩展了额外的功能。
http/2 现在或者将来会被所有主流浏览器支持。
chrome 40 支持 http/2 14 号草案,但是默认不开启。http/2 17 号草案(也就是最终草案),现在可以在 chrome canary 43(开发者预览版)里使用了,目前只有基于 tls(加密的)的 http/2 实现。 如需在 chrome 中启用 http/2,访问: <code>chrome://flags/#enable-spdy4</code>
firefox 支持 http/2,在第 36 版中默认启用,早在第 34 版中,就已经开始添加针对 http/2 的实验性支持。目前也只有基于 tls 的http/2 实现。
ie11 支持 http/2,但是只在 windows 10 beta 版里默认启用。目前也只有基于 tls 的 http/2 实现。
spartan 预计也会支持基于 tls 的 http/2,尽管微软为 windows 10 打造的新浏览器的有关细节尚未完全曝光。
safari 在 mac os x yosemite(10.10)和 ios 8 中默认支持 spdy,对于 http/2 的全支持预计在 2015 年底完成。
opera 默认支持 spdy。预计在 chrome 全部实现 http/2 最终草案的特性后全面支持 http/2。
iis(互联网信息服务)在 windows 10 beta 版中支持 http/2。
openlitespeed 1.3.8 和 1.4.5 支持 http/2 第 17 号草案。
apache 通过 mod_spdy 模块支持老版本的 spdy,目前这个模块已经停止开发。
litespeed web 服务器目前支持 spdy/3.1。
nginx 通过一个模块提供针对 spdy(draft 3.1) 的实验性支持,计划在 2015 年底支持 http/2。
lighttpd 在版本 1.x 中没有支持 spdy 或 http/2 的计划
正如我们所探索的,http/2 早就应该为升级 web 而出现,当它在接下来的几年中被广泛接受,网站和其它 web 服务将会变得更快,比以前任何时候更加能干。感谢有远见的浏览器厂商们,http/2 将会增强用户的隐私和安全。我认为对于整个 web 生态来说,http/2 是一次至关重要的飞跃,未来有许多新的事业正等着我们去开拓。
原文发布时间:2015-03-27
本文来自云栖合作伙伴“linux中国”