繁体   English   中英

接收方是否可以减少 HTTP/2 流控制窗口?

[英]Is it possible for the receiver to decrement an HTTP/2 stream flow control window?

RFC 7540 的第 6.9 节描述了 HTTP/2 流控制的机制。 每个连接都有一个流量控制窗口,该连接上的所有流都有另一个流量控制窗口。 它为接收者提供了一种为流设置初始流控制窗口的方法:

两个端点可通过包括用于一个值调整为新流的初始窗口大小SETTINGS_INITIAL_WINDOW_SIZESETTINGS框架,所述连接序言的形成部分。

以及接收方增加连接和流控制窗口的一种方式:

WINDOW_UPDATE帧的有效载荷是一个保留位加上一个无符号的 31 位整数,指示除了现有的流量控制窗口之外,发送方可以传输的八位字节数。 流控制窗口增量的合法范围是 1 到 2^31-1 (2,147,483,647) 个八位字节。

[...]

接收 WINDOW_UPDATE 帧的发送者按帧中指定的数量更新相应的窗口。

以及接收器一次增加或减少所有流(但不是连接)的流量控制窗口的方法:

SETTINGS_INITIAL_WINDOW_SIZE发生变化时,接收者必须通过新值和旧值之间的差异来调整它维护的所有流控制窗口的大小。

但据我所知,接收者无法在不改变初始窗口大小的情况下减少单个流的流量控制窗口

那是对的吗? 如果是这样,为什么不呢? 如果您在单个连接上多路复用许多长期存在的流,这似乎是一件合理的事情。 您可能有一些 BDP 控制的用于整个连接的内存预算,分配给各个流,并且正在根据每个流最近的带宽需求调整其获得的比例。 如果其中一个暂时空闲,您希望能够将其窗口重置为小,这样它就不会占用内存预算,而不会影响其他流,并且不会导致无法接收新流。

(当然我知道存在竞争,并且发送方可能在收到减量之前已经发送了数据。但是由于上面的SETTINGS_INITIAL_WINDOW_SIZE机制,窗口已经被允许为负,所以似乎允许这里也是一个负窗口。)

如果不依赖发送方的转发进度来吃掉流量控制窗口中的滞留字节,真的不可能做到这一点吗?


这里有更多关于我为什么对这个问题感兴趣的细节,因为我知道 XY 问题。

我正在考虑如何解决 RPC 流控制问题。 我有一个内存预算有限的服务器,传入的流具有不同的优先级,它们应该允许消耗多少内存。 我想在它们之间实现诸如加权最大-最小公平性之类的东西,调整它们的流量控制窗口,使它们的总和不超过我的内存预算,但是当我们不受内存限制时,我们可以获得最大吞吐量。

出于效率原因,希望在单个连接上多路复用不同优先级的流。 但是随着需求的变化或其他连接的出现,我们需要能够向下调整流控制窗口,这样它们的总和仍然不超过预算。 当流 B 出现或获得更高的优先级但流 A 坐在一堆流量控制预算上时,我们需要减少 A 的窗口并增加 B 的窗口。

即使没有多路复用,同样的问题也适用于连接级别:据我所知,没有办法在不改变初始窗口大小的情况下向下调整连接流控制窗口。 当然,它会随着客户端发送数据而向下调整,但我不想依赖于客户端的转发进度,因为这可能需要任意长的时间。

可能有更好的方法来实现这一目标!

有 N 个流的服务器,其中一些空闲和一些主动下载数据到客户端,通常会将连接窗口重新分配给活动流。

例如,假设您正在观看电影同时从同一服务器下载一个大文件。

连接窗口是 100,每个流也有一个 100 的窗口(很明显,在许多流的情况下,所有流窗口的总和将被连接窗口限制,但如果只有一个流,它可以是最大的)。

现在,当您观看和下载每个流时,将获得 50 个。

如果您暂停电影,并且服务器知道这一点(即它不会耗尽电影流窗口),那么服务器现在只需要提供一个流,连接窗口为 100 和一个流(下载一个)它的窗口也为 100,因此将整个窗口重新分配给活动流。

如果客户端没有告诉服务器电影已暂停,您只会遇到问题。 在这种情况下,服务器将继续发送电影数据,直到电影流窗口耗尽(或准耗尽),并且客户端不会确认该数据,因为它已暂停。 此时,服务器注意到数据未被一个流确认并停止向其发送数据,但当然会占用部分连接窗口,从而减少活动下载流的窗口。

从服务器的角度来看,它有一个非常好的连接,其中一个流(下载流)以最大速度运行良好,但另一个流打嗝并耗尽其窗口并导致另一个流变慢(可能停止),即使是相同的连接!

显然,这不可能是连接/通信问题,因为一个流(下载流)在最大速度下运行得非常好。 因此,这是一个应用程序问题。

服务器上的 HTTP/2 实现不知道其中一个流是可以暂停的电影——应用程序必须将其与服务器通信并保持尽可能大的连接窗口。

引入一个新的 HTTP/2 框架来“暂停”下载(或改变现有框架的语义以适应“暂停”命令)会使协议相当复杂,对于 100% 应用程序驱动的功能——它是必须触发发送“暂停”命令的应用程序,但此时它可以向服务器发送自己的“暂停”消息,而不会使 HTTP/2 规范复杂化。

这是一个有趣的例子,HTTP/1.1 和 HTTP/2 的行为非常不同,需要不同的代码以类似的方式工作。

使用 HTTP/1.1,您将有一个用于电影的连接和一个用于下载的连接,它们将是独立的,并且客户端应用程序不需要与服务器通信电影已暂停——它可以停止从电影中读取连接直到它变成 TCP 拥塞而不影响下载连接——假设服务器是非阻塞的以避免可扩展性问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM