High一下!

http2.0小结

纸上得来终觉浅,觉知此事要躬行

前言

如今,http1.1是互联网中的主要协议,随着web技术的飞速发展,http1.1已经无法满足用户对性能的要求,此后谷歌推出SPDY,意在解决http1.1中广为人知的性能问题,其在被行业采用并证明能够大幅提升性能后,已经具备了成为一个标准的条件。

Http2.0是http协议自1999年http1.1发布后的首个更新,主要基于SPDY协议,於2015年正式发表。

http2.0变化

二进制分帧

帧:http2.0数据通信的最小单位。

消息(message):指http2.0中逻辑上的http消息。例如请求和响应,消息由一个或多个帧组成。

流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的证书ID。

http2.0采用二进制格式传输数据,而非http1x的文本格式,二进制协议解析起来更高效。

Http1.x的请求和响应报文,都是起始行,首部和整体正文(可选)组成,各部分之间以文本换行符分隔。http2.0将请求和响应数据分割为更小的帧,并且它们采用二进制编码。

http2.0中,同域名下所有通信都在单个连接上完成(多路复用中介绍),这个连接可以承载任意数量数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。

多路复用

多路复用,代替原来的序列和阻塞机制。所有的请求都是通过==一个TCP==连接并发完成。

http1.x中,如果想并发多个请求,必须使用多个tcp连接,并且浏览器为了控制资源,还会对单个域名有6-8个数限制,如下图,红色圈出来的请求就因域名链接数超过限制,而被挂起等待了一段时间:

在http2.0中,有了二进制分帧后,就不再依赖TCP连接去实现多流并行了:

  • 同域名下所用通信都在单个连接上完成
  • 单个连接可以承载任意数量的双向数据流
  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧可以乱序发送,因为根据帧首部的流标识可以重新组装

这一特性,性能会有极大提升,因为:

  • 同个域名下只需要占用一个TCP连接,消除了因多个TCP连接而带来的延时和内存消耗
  • 单个连接上可以并行交错请求和响应,之间互不干扰
  • 在http2.0中,每个请求都可以带一个31bit的优先值,0表示最高优先级,数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧

服务器推送

服务端可以在发送页面html时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把js和css文件推送给客户端,而不需要客户端解析html在请求发送这些请求。服务端可以主动送,客户端也有权利选择接收与否,如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过RST_STREAM帧来拒收。主动推送也遵守同源策略,服务端不会随便推送第三方资源给客户端。

头部压缩

Http1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续发送。http2.0对消息头部采用HACK(专门为http2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络流量。而http1.x每次请求,都会携带大量冗余头部信息,浪费很多带宽资源,如果算cookie,增加的负荷会达到上千字节,为了减少开销并且提升性能,http2.0会压缩首部元数据。

  • http2.0在客户端和服务端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送
  • 首部表在http2.0的连接存续期内始终存在,由客户端和服务端共同渐进的更新
  • 每个新的首部键-值对要么被追加到当前表尾部,要么替换表中之前的值

于是,http2.0连接的两端都知道已经发送了那些首部,这些首部的值是什么,从而针对之前的数据至编码发送这些差异的数据。在通信期间几乎不会改变的键值对只需要发送一次即可,这就大大提高了数据的载荷。

头部压缩需要客户端和服务端做好以下工作:

  • 维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称和值的组合
  • 维护一份相同的动态字典(Dynamic Table),可以动态的添加内容
  • 支持基于静态哈夫曼编码(Huffman Coding)

静态字典的作用有两个:

  1. 对于完全匹配的头部键值对,可以直接使用一个字符表示
  2. 对于头部名称可以匹配的键值对,可以将名称使用一个字符表示

哈夫曼编码的核心理念就是使用最少的位数表示最多的信息,HTTP2.0中这份哈夫曼编码表是根据一个大样本的HTTP报头的统计数据生成,经常出现的字符会用较短的二进制数标识,出现频率较低的字符用较长的二进制数标识,这样就保证了综合来看报头信息占用了较少的空间,进一步压缩了报头信息。

在服务端接收到压缩过的报头信息后,会先进行哈夫曼编码解码,得到报首信息后,再结合维护的静态字典和动态字典信息得出完整的报首信息,随后进行请求的处理和响应。在需要更新动态字典信息时,对字典进行更新。

结语

向HTTP2.0的迁移不可能瞬间完成,无论服务器端还是客户端都需要进行必要的更新升级才能使用。好消息是,大多数现代浏览器都内置有高效的后台升级机制,对大多数既有用户来说,这些浏览器可以很快的支持HTTP2.0,不会带来很大困扰。然而,服务器端和中间设备的升级、更新就不是那么容易,是一个长期的过程,而且很费力、费钱。

HTTP1.X至少还会存续十年以上,大多数服务器和客户端在此期间必须同时支持1.x和2.0标准。于是,支持HTTP2.0的客户端在发起新请求之前,必须能发现服务器及中间设备是否支持HTTP2.0协议。

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章