关于HTTP/2 RFC实现的流量控制问题。

4
我正在构建一个http/2客户端,对于RFC和我应该如何处理实现特别是与流控制有关的问题有疑问。
我知道流控制使用基于信用的窗口大小系统,但我不确定如何处理窗口耗尽的情况。
1. 当窗口被耗尽时,我是永久阻塞直到WINDOW_UPDATE帧释放了一些东西吗?还是会有一个合理的超时时间?
2. 当窗口被耗尽时,我需要暂停发送所有帧吗?RFC指出流中帧的顺序很重要,特别是标题和数据帧,但它并没有明确说明在窗口耗尽时应暂停所有帧。这对我来说有点模糊,因为只有数据帧才会影响窗口大小。所以我是要阻止发送所有帧还是只有头/数据帧?这个答案在连接流控制上下文和流流控制上下文中是否不同?
1个回答

2

连接中有一个流量控制窗口,还有每个流的一个窗口。

1. 如果连接窗口已经用完,你需要等待 WINDOWS_UPDATE。你可以设置超时时间。如果超时,你唯一的解决方法是关闭连接并重试。

2. 如果一个流的连接窗口已经用完,只有该流会暂停。

在所有情况下,只会暂停 DATA 帧。其他类型的帧不受流量控制影响。

如果你正在实现一个客户端而不是服务器,你更关心自己发送 WINDOW_UPDATE 帧。除非你需要频繁地进行 POST 和 PUT(即向服务器发送数据)。

在我作为 HTTP/2 服务器 的开发者的经验中,我发现将 HTTP/2 帧分组成“列车”很方便。对于除 HEADERS、PUSH_PROMISE 和 CONTINUATION 之外的所有帧,一列车仅由该帧组成。对于 HEADERS 和 PUSH_PROMISE,一列车包括该帧和任何后续的 CONTINUATION 帧。然后按以下优先级将列车放入优先队列(第一个优先级最高):

  1. PING帧:您希望对等方准确确定延迟,因此您会尽快处理这些帧并尽快发送答案。
  2. SETTINGS、WINDOW_UPDATE、RST_STREAM、GO_AWAY
  3. PUSH_PROMISE和HEADERS帧。HTTP/2规范允许两种(实际上是三种)类型的HEADERS帧:一种作为HTTP标头本身发送的帧,另一种是尾随帧。在这里我谈论的是第一种。
  4. DATA帧。如果您正在实现优先级设置,您可能希望在此进一步设置帧的优先级。

每当通道可用于发送时,您都会发送优先级队列中最高优先级的数据流。


你是否可以按照HEADERS、DATA、HEADERS的顺序排队帧,只暂停发送DATA帧,然后发送两个HEADERS帧,从而混乱事物的顺序?或者说,流是否可能进入这样一种状态,在没有完成DATA(到达结束流)的情况下按照这个顺序排队帧?我的担忧是,仅暂停DATA帧是否会导致此类问题... - Redth
您可以以任何顺序发送不同流的HEADERS,只要对于单个流的流程保持一致:HEADERS、DATA、HEADERS(实际上是可选的尾部)。换句话说,如果您暂停了流X的DATA帧,则无法发送其尾部。但是,您可以发送流Y的HEADERS。 - dsign
如果您正在发送一系列的HEADERS / PUSH_PROMISE和CONTINUATION,请勿在中间发送任何内容。 - dsign
如果我在流X上发送了HEADERS、DATA,那么什么算作trailers呢?这就是我的困惑所在,如果流量控制窗口已经耗尽,那么哪些帧可以发送到流上呢?听起来像是如果没有发送任何DATA,那么HEADERS(或CONTINUATION)是可以的……那么应该遵循哪些逻辑规则呢? - Redth
拖车是一个头帧的列车,可选地在数据发送完成后发送连续帧。大多数情况下,您不会使用它们(尽管我正在游说将其用于缓存摘要)。请查看RFC的第8.1节,其中定义了单个请求或响应的帧顺序。 - dsign
1
非常好的回答和跟进评论,感谢您的帮助! - Redth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接