2.5 从HTTP/1.1到HTTP/2
在1999年HTTP/1.1走上历史舞台之后,HTTP并没有真正发生改变。在2014年发布的RFC(Request for Comments,意见征集稿)中,再次澄清了此规范,但这个版本的规范更多的是一个文档记录,并没有对协议做什么变更。工作组曾经展开过新版本的工作(HTTP-NG),该工作本应对HTTP的工作方式做完全的重新设计,但是1999年该工作被中止了。人们普遍感觉这些变化太复杂,无法推广。
2.5.1 SPDY
2009年,Google的Mike Belshe和Robert Peon宣布,他们在开发一个叫作SPDY(发音同“speedy”,不是一个缩写)的新协议。他们已经在实验环境中验证了这个协议,结果很好,页面加载时间改善了65%。他们是在排名前25的网站的复制版本上测试的,不是虚构网站。
SPDY基于HTTP构建,没有从根本上改变协议。就像HTTPS封装了HTTP,但是不改变它的底层机制。HTTP方法(GET、POST等)和HTTP首部的概念在SPDY中依然存在。SPDY工作在更低的层面,并且对开发者、服务器管理员和(最重要的)用户来说,SPDY几乎是透明的。所有的HTTP请求简单地被转换为SPDY请求,发向服务器,然后再转换回来。对于更高层的应用(像JavaScript应用)来说,SPDY请求和其他的HTTP请求一样。另外,SPDY的实现只基于加密的HTTP(即HTTPS)。HTTPS使得在客户端和服务器间中转消息的网络设施无法查看消息的结构和格式。所以,所有现存的网络设备,如路由、交换机和其他基础设施,不用做任何改变就能处理SPDY消息,甚至不用知道它们在处理SPDY消息还是HTTP/1消息。SPDY本质上是向后兼容的,带来的风险和改动较少,这也是它能获得成功而HTTP-NG失败的一个决定性原因。
HTTP-NG尝试解决HTTP/1的多种问题,而SPDY的主要目标是解决HTTP/1.1的性能问题。它引入了一些关键的概念来解决HTTP/1.1的问题:
• 流多路利用 —— 请求和响应使用单个TCP连接传输数据,它们被分成不同的数据包,以流的方式分组。
• 请求优先级 —— 在同时发送所有请求时,为了避免引入新的性能问题,引入了请求优先级的概念。
• HTTP首部压缩 —— HTTP体早就可以压缩了,现在首部也可以压缩了。
如果像HTTP一样,SPDY是一个基于文本的请求-响应协议,这些功能就不可能实现,所以SPDY变成了一个二进制协议。这个改动使得我们可以在一个连接上处理较小的消息,然后将它们合并为较大的HTTP消息,这跟TCP将HTTP消息拆分为TCP数据包的模式非常像,而且这种拆分对于大多数HTTP实现来说是透明的。SPDY在HTTP层实现了TCP的相关概念,所以它可以同时传输不同的HTTP消息。
像服务器推送这种高级功能,允许服务器返回额外的资源。如果你请求主页面,服务器可以在主页面的请求中推送所需要的CSS文件内容。这种方式可以节省浏览器再次发送CSS请求的时间,也能避免将critical CSS变为行内样式带来的复杂度。
Google地位超然,既拥有一个主流浏览器(Chrome),又手握一些流行的网站(如www.google.com),所以它可以在服务器和浏览器端实现新的协议,并在线上做更大规模的实验。2010年9月,Chrome开始支持SPDY,到2011年,所有的Google服务都添加了对SPDY的支持[18]——无论从哪方面看,这个过程都堪称迅速。
SPDY几乎在一夜之间获得了成功,其他浏览器和服务器迅速添加了对它的支持。Firefox和Opera在2012年添加了支持。在服务端,Jetty首先支持SPDY,其他像Apache和Nginx也很快添加了支持。支持SPDY的绝大多数网站都运行在后两个Web服务器上。使用SPDY的网站(包括Twitter、Facebook和WordPress)获得了与Google相同的性能提升。除了建立连接的性能以外,其他的性能几乎没有下降。据w3techs.com称,支持SPDY的网站已经占总数的9.1%[19],但是HTTP/2问世之后,一些浏览器开始取消对SPDY的支持。自2018年初以来,SPDY的使用率急剧下降,如图2.17所示。
图2.17 自HTTP/2发布以来,SPDY的支持率下降
2.5.2 HTTP/2
SPDY证明了一件事,HTTP/1.1可以优化,这不仅仅是理论上的证明,而且有现实中大型网站的案例。2012年,IETF的HTTP工作组注意到SPDY的成功,并开始征集下一版本HTTP的提案[20]。SPDY自然成为了下一版本的基础,因为相较于接受新的提案,它已经过现实的考验,虽然工作组避讳这样说(有些人会对这一立场提出异议,见第10章)。
不久(考虑新的提案)之后,2012年11月,基于SPDY发布了HTTP/2初稿[21]。在接下来的两年内,人们对此稿进行了一些细节上的改善(特别是关于流和压缩的使用)。在第4、5、7、8章,我们会详细介绍其中的技术细节,这里只简单介绍。
在2014年底,HTTP/2规范作为互联网的标准被提出,而在2015年5月,被正式通过,这就是RFC 7450[22]。HTTP/2很快获得了支持,主要因为它很大程度上是基于SPDY实现的,而很多浏览器和服务器已经实现了相关的技术。Firefox从2015年2月开始支持HTTP/2,Chrome和Opera在同年3月也添加了对它的支持。IE 11、Edge和Safari也在同年晚些时候添加了支持。
Web服务器也很快就添加了对HTTP/2的支持,而且在协议标准化的过程中产生了一些中间版本,很多服务器同时也支持这些版本。LiteSpeed[23]和H2O[24]是首批支持HTTP/2的Web服务器。到2015年底,被绝大多数互联网用户所使用的三大主要Web服务器(Apache、IIS和Nginx)添加了对HTTP/2的支持,尽管在默认情况下只作为实验功能,并未开启。
在2018年9月,根据w3tech.com的数据,已经有30.1%的网站支持HTTP/2[25]。能取得这个成果,主要是因为CDN厂商以及主流网站的支持,但是对于一个只发布三年的技术来讲,已经足够引人注目。就像第3章要讲的,在服务端支持HTTP/2还需要付出一些努力。如果不是这个原因,HTTP/2的使用率还会更高。
我想要强调的是,HTTP/2已经向你走来,请尽情使用它。它已经在实际应用中得到验证,可以显著提高性能,而且它解决了本章中描述的HTTP/1.1的问题。