基本概念 基本数据结构( 二 )



HTTP/2没有规定接收方如何决定何时发送WINDOW_UPDATE帧、发送什么样的值,具体算法依赖服务器具体实现 。
nginx选择在接收窗口小于窗口最大值1/4时发送WINDOW_UPDATE帧,并且将窗口大小增长到最大值2^31-1
并不是所有服务器都这样实现的 。
比如有的实现是这样的,收到一个DATA帧,马上返回一个WINDOW_UPDATE帧,增长的值就是DATA帧的大小

发送DATA帧h2c->send_window -= frame_size;stream->send_window -= frame_size;
管理帧的处理有一些与请求数据无关的帧,对连接和流的行为和状态能够进行控制,暂且叫它管理帧 。
比如SETTING WINDOW_UPDATE帧,就能够对流量窗口进行修改
接收SETTING帧
stream->send_window += value-h2c->init_window//所有的stream都会被设置,但是不超过NGX_HTTP_V2_MAX_WINDOWh2c->init_window = value;//
接收WINDOW_UPDATE帧if (h2c->state.sid) {//判断是不是设置了sidnode = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);...stream = node->stream;...stream->send_window += window;}h2c->send_window += window;
正确使用流控看完HTTP/2 的send_window 在各种情形下的变化情况,可以发现从理念到实现上都非常简单,对于普通用户来说,可以将这个当成透明的 。
流量控制的定义是用来保护端点在资源约束条件下的操作 。例如,一个代理需要在很多连接之间共享内存,也有可能有缓慢的上游连接和快速的下游连接 。流量控制解决的情况是接收端在一个流上处理数据的同时同样想继续处理同个连接上的其他流 。
调度过程中不需要这种能力时可以广播一个最大值的流量控制窗口,增加接收新数据时的可用空间 。发送数据时总是受接收端广播的流量控制窗口的管理(见[RFC1323]) 。
资源约束下(例如内存)的调度可以使用流量来限制一个对等端可以消耗的内存数量 。需要注意的是如果在不知道带宽延迟乘积的时候启用流量控制可能导致无法最优的利用可用的网络资源(see RFC1323) 。
即便是对当前的网络延迟乘积有充分的认识,流量控制的实现也可能很复杂 。当使用流量控制时,接收端必须及时地从TCP接收缓冲区读取数据 。这样做可能导致在一些例如WINDOW_UPDATE的关键帧在HTTP/2不可用时导致死锁 。但是流量控制可以保证约束资源能在不需要减少连接利用的情况下得到保护 。


参考
http://blog.csdn.net/jianfyun/article/details/48549939
【基本概念 基本数据结构】https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-5.3
https://imququ.com/series.html
https://segmentfault.com/a/1190000002675667