一、HTTP/2简介

HTTP/2标准于2015年5月以RFC 7540正式发表,替换HTTP/1.1成为HTTP的实现标准。

HTTP/2保留、兼容HTTP/1.1的所有语义,与HTTP/1.*相比,主要区别包括:

  1. HTTP/2采用二进制格式而非文本格式
    • 高效紧凑传输解析
    • 更少错误倾向,没有了所谓的空白行、大写、换行符、空连接等
  2. HTTP/2是完全多路复用的,而非有序并阻塞的
    • HTTP/1.1默认情况下单个请求单个连接
    • HTTP/1.1流水线化pipelining方式导致较大/较慢的响应阻塞后续任务
    • HTTP/1.1无法解决线头阻塞的问题
    • 多路复用可以有效避免线头阻塞,多个请求-响应同一个连接内并行处理
  3. 只需一个连接即可实现并行
    • HTTP/1.*多个连接会占用过多网路资源,导致TCP堵塞和数据重传
    • HTTP/2单个连接内多个流(请求-响应)之间并行处理,减少网路资源占用,可避免了TCP频繁的打开、关闭
  4. 使用报头压缩,HTTP/2降低了开销
    • 传统浏览器网路报头一般在80-1400字节大小
    • 压缩头部可让报头更紧凑,更快速传输,有利于移动网络环境等
    • 压缩算法使用HPACK,更为高效、安全
  5. HTTP/2让服务器可以将响应主动“推送”到客户端
    • 传统方式:客户端请求,服务器响应,客户端逐一解析需要后续请求的图片、样式等资源,再次一一发送资源请求
    • HTTP/2服务器根据客户端请求,计算出响应内容所包含的资源,在客户端发起请求之前提前发送给客户端
    • 节省客户端主动发起请求的时间的往返时间

总的来说,就是HTTP/2更快更省更安全。    

二、HTTP/2性能对比

https://http2.akamai.com/demo 是Akamai公司建立的一个官方的演示,用以说明HTTP/2相比于之前的HTTP/1.1在性能上的大幅度提升。从Load time的对比可以很直观的看到两者的速度差异:

该页面包含HTTP/1.1HTTP/2两个frame,每一个frame包含364个请求,其中361个请求返回的图片组成中间的大图。

Protocol Load Time
HTTP/1.1 6.71s
HTTP/2 0.92s

相比之下HTTP/2减少了86%的请求时间

Protocol size
HTTP/1.1 864KB
HTTP/2 796KB

 相比之下HTTP/2减少了7.8%的请求开销

总结:从实际测试结果来看,HTTP/2能有效降低整体开销,特别是多路复用和并行请求,大幅度的减少请求时间,意义明显。

三、浏览器和服务端的支持

目前主流浏览器ChromeOpera, Firefox, IE 11SafariAmazon SilkEdge都支持HTTP/2

需要注意的是HTTP/2协议本身并没有要求它必须基于TLS(HTTPS)部署,但当前主流浏览器包括Chromefirefox,都明确只支持基于TLS部署的HTTP/2,因此对于服务端来说,就必须支持ALPNALPN是什么,这里有介绍Introducing ALPN)来完成HTTP/2的协议协商。

大部分Web Server都依赖OpenSSL库提供TLS,对于它们来说,是否支持ALPN完全取决于使用的OpenSSL版本,从OpenSSL 1.0.2开始支持ALPN

对于协商不到HTTP/2的请求,将会降级到HTTP/1.1来完成请求,没有兼容性问题。  

四、客户端的支持

   iOS方面,Apple对于HTTP/2的态度非常积极,从iOS9开始,提供了NSURLSession库用于支持HTTP/2

而要Android支持HTTP/2,首先离不开Java的支持。从公开文献得知,HTTP/2ALPN被包含了在Java9的新特性中,而Java9已经跳票到2017年7月。。。

那是不是就没法在Android客户端中使用HTTP/2了呢?

我们知道Android API中用于完成网络请求的URLConnection库已经在Andriod 4.x时代被替换成了基于OkHttp的实现,而不再是原本的Java封装。

OkHttp官网得知,从OkHttp2.5版本开始支持HTTP/2ALPN,但仅限于Android 5.0系统以上,由于我们不知道基于OkHttp封装的URLConnection所使用的版本,因此我们需要测试验证一下。

测试环境:

测试过程为分别通过URLConnectionOkHttp3.4.1发起网络请求,通过服务端log可以观察到客户端的请求是否协商HTTP/2成功,还是被降级到HTTP/1.1,验证结果如下:

* Android4.4 Android5.1 Android6.0  
URLConnection HTTP/1.1 HTTP/1.1 HTTP/1.1  
OkHttp3.4.1 HTTP/1.1 HTTP/2 HTTP/2  

由此可以看出,Android API原生不支持HTTP/2,而在Android 5.0以上的系统中,可以通过第三方库OkHttp来完成HTTP/2的请求。  

五、总结

  1. 相对于文本传输、串行处理的HTTP/1.1HTTP/2的二进制传输、报头压缩、多路复用等技术,无论是整体开销还是请求时间,性能优势明显,特别是在实际测试中,请求加载时间录得高达86%的提升;
  2. 主流浏览器内核都已经支持基于TLSHTTP/2
  3. Android API原生不支持HTTP/2,而在Android 5.0以上的系统中,可以通过第三方库OkHttp来完成HTTP/2的请求。

后记:在部署HTTP/2服务,编写Android demo发起HTTPSHTTP/2请求的时候着实费了一番周折,篇幅所限,将会在另一篇文章总结出来,以免以后再走弯路。