老青菜

HTTP/2.0 Flow Control

2019-06-13

根据rfc7540#section-5.2的描述,使用流进行多路复用会导致争用TCP连接,导致流阻塞。流量控制方案确保同一连接上的流不会破坏性地互相干扰。流量控制可以作用于单个流或者整个连接,是逐跳的,而且流量控制仅仅作用于Data Frame。

控制原理

TCP Sliding Window原理差不多,HTTP/2.0的Flow Control针对每个Stream也有一个Window窗口,只不过没有SEQ、ACK。
流量控制窗口Window是一个简单的整数,指示允许发送方能传输多少个八位字节。因此,窗口的大小间接衡量了接收者缓冲区的容量。

控制方式

接下来我们看一下如何控制这个窗口大小,HTTP/2.0支持两个帧来控制流量:SETTINGS Frame、WINDOW_UPDATE Frame。

SETTINGS Frame

设置帧(rfc7540#section-6.5),通过SETTINGS_INITIAL_WINDOW_SIZE参数,设置初始窗口大小,针对所有Stream生效。Payload格式如下:

    +-------------------------------+
    |       Identifier (16)         |
    +-------------------------------+-------------------------------+
    |                        Value (32)                             |
    +---------------------------------------------------------------+

SETTINGS_INITIAL_WINDOW_SIZE:窗口大小(以八位字节为单位),初始值为2^16-1(65,535)个Byte。

WINDOW_UPDATE Frame

窗口更新帧(rfc7540#section-6.9),通过该帧可以增加窗口大小,可以作用于某个Stream,或者整个连接。Payload格式如下:

    +-+-------------------------------------------------------------+
    |R|              Window Size Increment (31)                     |
    +-+-------------------------------------------------------------+

Window Size Increment:窗口增量,即除现有的流控制窗口外,发送者还可以发送的消息大小。增量的范围是1到2^31-1(2,147,483,647)Byte。

控制流程

那么流量控制过程具体是怎么样的呢?这里我简单的画了一个图:

  1. 首先初始Window Size是65535Byte,Client第一次发送了30000Byte,这时候Window Size=35535Byte;
  2. 第二次Client继续发送了25535Byte,这时候Window Size=10000Byte;
  3. 第三次Client继续发送了30000Byte,这时候Window Size只有10000Byte,发送了10000Byte之后,剩下的20000Byte继续等待窗口更新。这时候Window Size只有0Byte。
  4. 接收者Server消费了数据,释放了空间,发送Window Update Frame,通知Window Size增加100000Byte,这时候Window Size=100000Byte。而且Client又可以继续发送之前未发完的消息。

参考链接

rfc7540

Tags: HTTP
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章