HTTP/2协议–特性扫盲篇

 

HTTP/2协议–特性扫盲篇

随着web技术的飞速发展,1999年制定的HTTP 1.1已经没法知足你们对性能的要求,Google推出协议SPDY,旨在解决HTTP 1.1中广为人知的性能问题。SPDY获得了Chrome、Firefox和Opera的支持,不少大型网站(如谷歌、Twitter、Facebook、淘宝)都对兼容客户端使用SPDY。SPDY在被行业采用并证实可以大幅提高性能以后,已经具有了成为一个标准的条件。html

HTTP工做组采用了SPDY v2草案做为制定HTTP 2.0标准的起点,2014年12月将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2标准于2015年5月以RFC 7540正式发表。至此,SPDY完成了历史的使命,即将退出历史的舞台,HTTP/2粉墨登场。git

在HTTP的语义、HTTP方法、状态码、URI和首部字段等核心概念不变的状况下,HTTP/2实现了性能优化,HTTP/2具体有哪些变化呢?下面一一解答 O(∩_∩)O~github

二进制分帧(Binary Framing)

HTTP1.x以换行符做为纯文本的分隔符。web

HTTP/2将全部传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,咱们先了解几个概念:浏览器

  • 帧(Frame):HTTP/2通讯的最小单位,每一个帧包含帧首部,至少也会标识出当前帧所属的流。
  • 消息(Message):由一个或多个帧组合而成,例如请求和响应。
  • 链接(Connection):与 HTTP/1 相同,都是指对应的 TCP 链接;
  • 流(Stream):已创建的链接上的双向字节流。

在HTTP/2中,数据流以消息的形式发送,而消息由一个或多个帧组成,帧能够在数据流上乱序发送,而后再根据每一个帧首部的流标识符从新组装。二进制分帧是HTTP/2的基石,其余优化都是在这一基础上来实现的。缓存

多路复用(Request and Response Multiplexing)

HTTP1.x中,若是想并发多个请求,必须使用多个TCP连接,且浏览器为了控制资源,还会对单个域名有6-8的个数限制,以下图,红色圈出来的请求就因域名连接数已超过限制,而被挂起等待了一段时间:
Alt text
针对这一问题,咱们作了不少优化,例如合并请求、图片精灵、散列域名等性能优化

在 HTTP/2 中,有了二进制分帧以后,HTTP 2.0再也不依赖TCP连接去实现多流并行了,在HTTP/2:服务器

  • 同域名下全部通讯都在单个链接上完成。
  • 单个链接能够承载任意数量的双向数据流。
  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间能够乱序发送,由于根据帧首部的流标识能够从新组装。

这一特性,性能会有极大的提高,由于:cookie

  • 同个域名只须要占用一个TCP链接,消除了因多个TCP链接而带来的延时和内存消耗。
  • 单个链接上能够并行交错的请求和响应,之间互不干扰。

流优先级( Stream priority)

在HTTP/2中,每一个请求均可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就能够在处理不一样的流时采起不一样的策略,以最优的方式发送流、消息和帧。并发

服务器推送(Server push)

Server push是HTTP/2中一个很强大的功能:

  • 服务器除了响应客户端的请求外,还能够向客户端额外推送资源。
  • 服务器推送的资源有本身独立的URL, 能够被浏览器缓存,能够达到多页面共享。
  • 资源推送遵照同源策略,服务器不可随便推送第三方资源给客户端。
  • 客户端能够拒绝推送过来的资源。

有了这一特性,咱们能够作什么?

  • 应用能够经过额外的http头部,列出须要服务器推送哪些资源。
  • 服务器能够解析请求的html,推测出客户端接下来须要请求的资源,而后提早向客户端推送。
  • 等等

头部压缩(Header Compression)

HTTP每一次通讯都会携带一组头部,用于描述此次通讯的的资源、浏览器属性、cookie等,例如
Alt text

在HTTP 1.x中,这些信息都是以纯文本协议发送的,给每一个请求增长了不小的负荷。

为了减小这块的开销并提高性能, HTTP/2会压缩这些首部:

  • HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储以前发送的键-值对,对于相同的数据,再也不经过每次请求和响应发送;
  • 首部表在HTTP/2的链接存续期内始终存在,由客户端和服务器共同渐进地更新;
  • 每一个新的首部键-值对要么被追加到当前表的末尾,要么替换表中以前的值。

例如:下图中的两个请求, 请求一发送了全部的头部字段,第二个请求则只须要发送差别数据,这样能够减小冗余数据,下降开销。

Alt text

咱们来看一个实际的例子,下面是用WireShark抓取的访问google首页的包:
Alt text

上图是是访问https://www.google.com/抓到的第一个请求的头部,能够看到头部的内容,总共占用了437 bytes,咱们选中头部的cookie,能够看到cookie总共占用了118 bytes。接下来咱们看看第二个请求的头部:

Alt text
从上图能够看到,得益于头部压缩,第二个请求中cookie只占用了1个字节,咱们来看看变化了的Accept字段:
Alt text
因为Accept字段与请求一中的内容不一样,须要发送给服务器,因此占用了29 bytes。

应用层协商协议(APLN:Aplication Layer Protocol Negotiation)

客户端、服务器都须要升级才能支持HTTP 2.0,升级过程当中就存在HTTP1.一、HTTP 2.0并存的状况,然而他们都使用的80端口,那么如何来选择使用什么协议通讯呢?

APLN就是为了解决这个问题的,经过协商来选择通讯的协议:

  1. 客户端发起请求,若是支持HTTP/2,则带upgrade头部:
    GET /page HTTP/1.1
    Host: server.example.com
    Connection: Upgrade, HTTP2-Settings
    Upgrade: HTTP/2.0
    HTTP2-Settings: (SETTINGS payload)
  2. 服务器不支持,则拒绝升级,经过HTTP1.1返回响应
    HTTP/1.1 200 OK
    Content-length: 243
    Content-type: text/html
    (... HTTP 1.1 response ...)
  3. 服务器支持,则接受升级,切换到新分帧,使用HTTP/2通讯。
    HTTP/1.1 101 Switching Protocols
    Connection: Upgrade
    Upgrade: HTTP/2.0
    (... HTTP 2.0 response ...)

使用协议协商,不管是哪种状况,都不须要额外的往返,若是客户端经过记录或者其余方式,知道服务器支持HTTP/2,则直接使用HTTP/2通讯,无需再协议协商。

Ending

最后,简而概之,HTTP/2的经过支持请求与响应的多路复用来减小延迟,经过压缩HTTP首部字段将协议开销降至最低,同时增长对请求优先级和服务器端推送的支持。

HTTP/2性能获得了极大的提高,咱们在HTTP 1.1时代作的有些优化反而成了鸡肋,在升级过程当中,如何让HTTP/2 和 HTTP 1.1的用户都能获得最优的性能,这是对于咱们的另一大挑战。

参考资料:

  1. 《High Performance Browser Networking》 –Ilya Grigorik;
  2. 《Web性能权威指南》-李松峰翻译;
  3. Jerry Qu blog 中的HTTP/2专题;
  4. HTTP/2 rfc 7540;
  5. HTTP/2 协议 中英对照版 –百度 FEX
  6. 维基百科:HTTP/2
相关文章
相关标签/搜索