HTTP/2

2017-09-26  本文已影响139人  angeChen

HTTP/2 是一个二进制协议,这也就意味着它的可读性几乎为 0,但幸运的是,我们还是有很多工具,譬如 Wireshark, 能够将其解析出来。

在了解 HTTP/2 之前,需要知道一些通用术语:

Frame

是 HTTP/2 里面最小的数据传输单位,一个 Frame 定义如下

+-----------------------------------------------+
|                 Length (24)                   |
+---------------+---------------+---------------+
|   Type (8)    |   Flags (8)   |
+-+-------------+---------------+-------------------------------+
|R|                 Stream Identifier (31)                      |
+=+=============================================================+
|                   Frame Payload (0...)                      ...
+---------------------------------------------------------------+

Multiplexing

HTTP/2 通过 stream 支持了连接的多路复用,提高了连接的利用率。Stream 有很多重要特性:

Priority

因为一条连接允许多个 streams 在上面发送 frame,那么在一些场景下面,我们还是希望 stream 有优先级,方便对端为不同的请求分配不同的资源。譬如对于一个 Web 站点来说,优先加载重要的资源,而对于一些不那么重要的图片啥的,则使用低的优先级

我们还可以设置 Stream Dependencies,形成一棵 streams priority tree。假设 Stream A 是 parent,Stream B 和 C 都是它的孩子,B 的 weight 是 4,C 的 weight 是 12,假设现在 A 能分配到所有的资源,那么后面 B 能分配到的资源只有 C 的 1/3

Flow Control

HTTP/2 也支持流控,如果 sender 端发送数据太快,receiver 端可能因为太忙,或者压力太大,或者只想给特定的 stream 分配资源,receiver 端就可能不想处理这些数据。譬如,如果 client 给 server 请求了一个视频,但这时候用户暂停观看了,client 就可能告诉 server 别在发送数据了

虽然 TCP 也有 flow control,但它仅仅只对一个连接有效果。HTTP/2 在一条连接上面会有多个 streams,有时候,我们仅仅只想对一些 stream 进行控制,所以 HTTP/2 单独提供了流控机制。Flow control 有如下特性:

这里需要注意,HTTP/2 默认的 window size 是 64 KB,实际这个值太小了,可以直接设置成 1 GB

HPACK

在一个 HTTP 请求里面,我们通常在 header 上面携带很多该请求的元信息,用来描述要传输的资源以及它的相关属性。在 HTTP/1.x 时代,我们采用纯文本协议,并且使用 \r\n 来分隔,如果我们要传输的元数据很多,就会导致 header 非常的庞大。另外,多数时候,在一条连接上面的多数请求,其实 header 差不了多少,譬如我们第一个请求可能 GET /a.txt,后面紧接着是 GET /b.txt,两个请求唯一的区别就是 URL path 不一样,但我们仍然要将其他所有的 fields 完全发一遍

HTTP/2 为了解决这个问题,使用了 HPACK。
HPACK 提供了一个静态和动态的 table,静态 table 定义了通用的 HTTP header fields,譬如 method,path 等。发送请求的时候,只要指定 field 在静态 table 里面的索引,双方就知道要发送的 field 是什么了

对于动态 table,初始化为空,如果两边交互之后,发现有新的 field,就添加到动态 table 上面,这样后面的请求就可以跟静态 table 一样,只需要带上相关的 index 就可以了

上一篇 下一篇

猜你喜欢

热点阅读