几个概念
帧(frame):HTTP/2 数据通信的最小单位,指 HTTP/2 中逻辑上的 HTTP 消息。
帧格式的组成部分:
length: frame payload 的长度;
Frame Payload: frame 携带的可变长数据,可为空;
type:frame 的类型;
flag: 保留给frame 的类型使用;
R: 保留的一个 bit,没有任何作用;
Stream Identifier: unsigned 31 位整数id,用来区分 stream;
消息:一个完整的请求或者响应,比如请求、响应等,由一个或多个 Frame 组成。
流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数标识符ID。
1、新特性之 二进制分帧(Binary Format)
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式。HTTP/2将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证 http 的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,HTTP 1.X中的首部信息 header 封装到 Headers 帧中,而request body 被封装到Data帧中。
HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
2、新特性之 多路复用(Multiplexing)
HTTP 1.x 中,客户端浏览器在同一时间,针对同一域名下的请求会有一定数量的限制,超过限制数目的请求会被阻塞。且如果想并发多个请求,必建立多个 TCP 链接。
在 HTTP/2 中,有了新的分帧机制后,它将不再依赖 TCP 连接去实现多流并行了,在 HTTP/2中:
同域名下所有通信都在单个连接上完成;
单个连接可以承载任意数量的双向数据流;
数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为可以根据帧首部的流标识重新组装。
这一特性带来了性能上的提升:
同个域名只需要占用一个 TCP 连接,消除了因多个 TCP 连接而带来的延时和内存消耗;
单个连接上可以并行交错的请求和响应,之间互不干扰;
在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。
上图展示了HTTP/2中一个连接上的多个传输数据流:客户端向服务端传输 stream5,同时服务端向客户端乱序发送stream1和stream3。这次连接上有三个响应请求乱序并行交换。
举例理解两种协议的传输过程(要从A地到B地去取货物):
HTTP 1.x 过程:卡车1从A地出发,到B地取到货物后返回,卡车1返回到A地卸下货物后,卡车2才开始再从A地出发去B地取货,然后在返回A地,如此有序往返。
HTTP/2 过程:卡车1、2、3、4、5从A地无序全部出发,到B地取货后返回A地,然后根据卡车号牌卸载对应货物。
明显第二种方式运输的货物多,且道路利用率高。
3、新特性之 头部压缩(Header Compression)
HTTP 1.x 的头部带有大量信息用于描述这次通信的的资源、浏览器属性、cookie等,而且每次都要重复发送。HTTP/2 使用encoder来减少需要传输的header大小。即:
HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的 键-值 对,对于相同的数据,不再通过每次的请求和响应发送;
首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进更新;
每个新的首部 键-值 对要么被追加到当前表的末尾,要么替换表中之前的值。
例如:下图中的两个请求, 请求1 发送了所有的头部字段,请求2 则只需要发送差异数据就行了,这样可以减少冗余数据,降低开销。
4、新特性之 服务端推送(Server Push)
服务端可以在发送页面HTML时主动向客户端推送其它资源,而无需等到客户端浏览器解析到相应位置重新发起请求再响应。
具体而言,当服务端需要主动推送某个资源时,便会发送一个 Frame Type 为 PUSH_PROMISE 的 Frame,里面带了 PUSH 需要新建的 Stream ID。意思是告诉客户端:接下来我要用这个 ID 向你推送东西,你准备好接着。客户端解析 Frame 时,发现它是一个 PUSH_PROMISE 类型,便会准备接收服务端要推送的流。
ps:服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。
HTTP/2的性能瓶颈
使用 HTTP/2 会让性能带来很大提升,但也会带来新瓶颈。因为所有的压力集中在底层一个TCP连接上,TCP很可能就是性能瓶颈,比如TCP分组的队首阻塞问题,单个TCP packet丢失导致整个连接阻塞,此时所有消息都会受到影响等。因此,服务端对HTTP/2下的TCP配置优化至关重要。
参考文档:https://zhuanlan.zhihu.com/p/26559480