0%

HTTP2协议

HTTP2是HTTP协议的一个重大的修订版本,用于解决随着Web发展HTTP1.1逐渐无法满足需求对开发者和用户造成负担的问题。

在HTTP1.1中,客户端需要多个连接才能实现并发和缩短延迟,同时HTTP1.1不会压缩请求和响应标头,导致不必要的网络流量以及等等问题。

二进制分帧层

HTTP2大致可以分为两个部分:

  • 分帧层:HTTP2实现多路复用能力的核心部分

  • 数据层:也就是HTTP及其关联数据的部分

分帧层是HTTP2所有性能增强的核心,定义了如何封装HTTP消息并在客户端和服务端之间进行传输。

HTTP/2 二进制分帧层

分帧层不影响HTTP的语义,不同的是传输期间的修改方式进行了变化。HTTP1.1以换行符(\r\n)作为换行符,解析速度慢且容易出错,在解析时需要不断地读入字节直到遇到分隔符为止。HTTP2将所有传输的信息分割为更小的消息和帧,并采用二进制格式进行编码,虽然肉眼识别起来比较困难,但是方便了机器解析。HTTP2中帧的结构如下所示:

image-20210315135413353

这样一来HTTP2解析的实现和维护都可以更加简单。同时相比于HTTP1.1需要发送完上一个请求或响应才能发送下一个,HTTP2的请求和响应可以交错甚至多路复用。

数据流

在HTTP2中所有的通信都在一个TCP连接上完成,该连接承载任意数量的双向数据流。流指的是HTTP2上独立的双向的帧序列交换,可以将流看作是连接上的一系列帧,可以承载一条或者多条的消息、每条消息都是一条逻辑的HTTP消息,包含一个或者多个帧。帧是最小的通信单位,承载特定类型的数据,例如HTTP标头和消息负载等等。

流量控制

流量控制可以阻止发送方向接收方大量的发送数据,以免超出接收方的需求和处理能力。HTTP2提供了WINDOW_UPDATE帧来指示更新后的处理字节能力,这个帧可以告诉对方更新后的处理字节能力。默认的流量控制窗口为65535。

数据流优先级

HTTP/2 标准允许每个数据流都有一个关联的权重和依赖关系,可以向每个数据流分配一个介于1至256之间的整数,每个数据流和其他数据流之间存在显式的依赖关系。数据流依赖关系和权重的组合客户端可以构建出优先级树,表明倾向于如何接受响应。服务端也可以控制CPU、内存以及其他资源的分配来设定数据流处理的优先级,将高优先级响应以最优方式传输至客户端。

服务端推送

HTTP2中服务端可以向一个客户端发送多个响应,额外的推送资源,从而减少额外的延迟时间。

服务器为推送资源发起新数据流 (promise)

服务端决定要推送一个对象时,会构造出PUSH_PROMISE帧,表明服务器向客户端推送所述资源的意图。该帧首部的流ID用来关联相应的请求。服务端推送需要保证被发送的对象是可缓存的,method首部的值必须是安全幂等的方法。

当客户端收到PUSH_PROMISE帧的时候,可以根据自身情况选择拒绝数据流(通过RST_STREAM帧),如果客户端不拒收推送,那么服务端会继续进行推送流程,用PUSH_PROMISE来指明ID对应的流来发送对象。

首部压缩

在HTTP1.1中,首部信息始终以纯文本的形式进行传输,如果加上cookie信息,会增加很多无用的网络开销。为了减少此开销和提升性能,HTTP2会使用HPACK压缩请求和响应标头元数据。

HPACK通过静态哈夫曼代码对传输的首部字段进行编码,减少了各个传输的大小。HPACK要求客户端和服务端都维护和更新一个包含之前见过的标头字段的索引列表,对之前传输的值进行有效编码。

HPACK: HTTP/2 的标头压缩