今天,HTTP 1.1 已经变成互联网中主要的协议。可是在 HTTP 协议诞生初期却被认为是简单直接的协议。1996 年在 RFC 1945 中定义了 HTTP 1.0 规范,仅 60 页,到 1999 年在 RFC 2616 定义了 HTTP 1.1,增加到了 176 页。可是,随着 web 技术的飞速发展。 HTTP 1.1 已经没法知足用户对性能的要求,此后 Google 推出协议 SPDY,意在解决 HTTP 1.1 中广为人知的性能问题。SPDY 获得了 Chrome、Firefox 和 Opera 的支持,不少大型网站(如谷歌、Twitter、Facebook)都对兼容客户端使用 SPDY。SPDY 在被行业采用并证实可以大幅提高性能以后,已经具有了成为一个标准的条件。html
HTTP/2 是 HTTP 协议自 1999 年 HTTP 1.1 发布后的首个更新,主要基于 SPDY 协议。它由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工做小组进行开发。该组织于2014年12月将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2标准于2015年5月以RFC 7540正式发表。git
先来理解几个概念:github
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 web
HTTP/1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,而且它们采用二进制编码。 浏览器
HTTP/2 中,同域名下全部通讯都在单个链接上完成(多路复用中介绍),这个链接能够承载任意数量的双向数据流。每一个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间能够乱序发送,由于根据帧首部的流标识能够从新组装。缓存
多路复用,代替原来的序列和阻塞机制。全部就是请求的都是经过一个 TCP
链接并发完成。 HTTP 1.x 中,若是想并发多个请求,必须使用多个 TCP 连接,且浏览器为了控制资源,还会对单个域名有 6-8 的个数限制,以下图,红色圈出来的请求就因域名连接数已超过限制,而被挂起等待了一段时间: 服务器
在 HTTP/2 中,有了二进制分帧以后,HTTP/2 再也不依赖 TCP 连接去实现多流并行了,在 HTTP/2中:cookie
同域名下全部通讯都在单个链接上完成。网络
单个链接能够承载任意数量的双向数据流。并发
数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间能够乱序发送,由于根据帧首部的流标识能够从新组装。
这一特性,性能会有极大的提高,由于:
同个域名只须要占用一个 TCP 链接,消除了因多个 TCP 链接而带来的延时和内存消耗。
单个链接上能够并行交错的请求和响应,之间互不干扰。
在HTTP/2中,每一个请求均可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就能够在处理不一样的流时采起不一样的策略,以最优的方式发送流、消息和帧。
服务端能够在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端能够主动把JS和CSS文件推送给客户端,而不须要客户端解析HTML再发送这些请求。服务端能够主动推送,客户端也有权利选择接收与否。若是服务端推送的资源已经被浏览器缓存过,浏览器能够经过发送RST_STREAM帧来拒收。主动推送也遵照同源策略,服务器不会随便推送第三方资源给客户端。
HTTP 1.1请求的大小变得愈来愈大,有时甚至会大于TCP窗口的初始大小,由于它们须要等待带着ACK的响应回来之后才能继续被发送。HTTP/2对消息头采用HPACK(专为http2头部设计的压缩格式)进行压缩传输,可以节省消息头占用的网络的流量。而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了不少带宽资源。
HTTP 每一次通讯都会携带一组头部,用于描述此次通讯的的资源、浏览器属性、cookie 等,例如
为了减小这块的开销并提高性能, HTTP/2会压缩这些首部:
HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储以前发送的键-值对,对于相同的数据,再也不经过每次请求和响应发送;
首部表在HTTP/2的链接存续期内始终存在,由客户端和服务器共同渐进地更新;
每一个新的首部键-值对要么被追加到当前表的末尾,要么替换表中以前的值。
例如:下图中的两个请求, 请求一发送了全部的头部字段,第二个请求则只须要发送差别数据,这样能够减小冗余数据,下降开销。
咱们来看一个实际的例子,下面是用WireShark抓取的访问google首页的包:
上图是是访问https://www.google.com/抓到的第一个请求的头部,能够看到头部的内容,总共占用了437 bytes,咱们选中头部的cookie,能够看到cookie总共占用了118 bytes。接下来咱们看看第二个请求的头部:
从上图能够看到,得益于头部压缩,第二个请求中cookie只占用了1个字节,咱们来看看变化了的Accept字段:
因为Accept字段与请求一中的内容不一样,须要发送给服务器,因此占用了29 bytes。
PS: 这里有个akamai的HTTP /2 的演示连接,有兴趣的能够点击看看:https://http2.akamai.com/demo
浏览器和网络服务支持状况:http2支持清单
又拍云 CDN 当前已全平台支持 HTTP/2,并已默认开启。又因 HTTP/2 是在 HTTPS 协议的基础上实现的,因此只要使用又拍云 HTTPS 加速服务的域名,均可免费享受 HTTP/2 服务,无需作任何特殊配置。而开启HTTPS,只需完成证书申请与管理,无须繁杂流程,轻松实现网站与 Web 应用的 HTTPS 加密部署。
参考资料:
Jerry Qu blog 中的HTTP/2专题;
维基百科:HTTP/2
RFC 7540 – 超文本传输协议第2版(HTTP / 2)
FC 7541 – HPACK:HTTP / 2的头压缩:http://httpwg.org/specs/rfc7541.html
http2讲解:https://ye11ow.gitbooks.io/http2-explained/content/part2.html
附:
浏览器和网络服务支持状况:http2支持清单
HTTP/2 和 HTTP/1 速度对比:HTTP/2: the Future of the Internet
为何非全站升级HTTPS不可?https://zhuanlan.zhihu.com/p/26953410