1

正如规范所说:

流量控制特定于连接。两种类型的流量控制都在单跳的端点之间,而不是在整个端到端路径上。

而在6.9 WINDOW_UPDATE

两种类型的流量控制都是逐跳的,即仅在两个端点之间。中介不在依赖连接之间转发 WINDOW_UPDATE 帧。但是,任何接收方对数据传输的限制都会间接导致流控制信息向原始发送方传播。

但这怎么可能呢?似乎需要所有中介了解h2h2c协议,我有两个问题:

  1. HTTP/2 是一个相对较新的标准,我看到很多网站都启用了它(包括我的博客)。虽然我可以毫无问题地访问这些网站,但这是否意味着沿途的每个中间设备(如路由器和集线器等)已经实现了自己的 HTTP/2 堆栈和流量控制算法(因为 RFC7540 没有规定流量控制算法)?

  2. 大多数网站使用h2而不是h2c加密应用层数据。HTTP/2 的流量控制是由接收方发送WINDOW_UPDATE帧完成的,这也是应用层数据,那么中间设备如何知道这些数据是什么?如果他们无法解密数据并看到Window Size Increment部分,他们如何在不转发WINDOW_UPDATE帧的情况下完成流量控制?

在此处输入图像描述

4

2 回答 2

4

首先,一些更正。

令牌h2c指的是明文 HTTP/2(因此是cin h2c)。在第二个项目符号中,您说大多数网站都使用它,但实际上很少有人这样做,因为浏览器没有实现它。绝大多数网站使用h2.

令牌h2指的是 encrypted h2c,或等效h2c地通过 TLS。

当客户端和服务器协商说话h2时,客户端发送的字节被加密并一直加密传输到服务器。这意味着中介没有机会解密流量(谢谢)。

在这种情况下,HTTP/2规范所指的“跳”就是客户端和服务器之间的整个网段。

然而,HTTP/2 规范需要是通用的,并且在定义诸如 HTTP/2 之类的有线协议时不必担心浏览器和 Web 服务器如何交互。

想象这样一种情况,客户端对server1using执行 HTTP/2 请求h2,并且server1需要调用server2来完成请求,这次使用h2c. 例如,server1可以是前端“代理”,根据某些逻辑将请求转发到“正确的”后端服务器。

在这种情况下,您有 2 个跃点:c​​lient-server1 和 server1-server2。

每个跃点应用自己的流量控制。

例如,假设客户端将一个大文件上传到服务器。通常,客户端流控制发送窗口很小,例如默认的 65535 个八位字节。在停止上传之前,客户端最多只能发送 65535 个八位字节。

这 65535 个八位字节由server1. 现在server1成为客户端以便与server2. 让我们假设server1的客户端在与 通信时配置了一个小得多的流控制窗口server2,比如说只有 16384 个八位字节。

在此示例中,server1将上传延迟到server216384 个八位字节后,并且必须设法保持剩余的 65535-16384 个八位字节等待server2通知(通过 WINDOW_UPDATE 帧)上传的数据已被消耗。

server1客户端收到来自 WINDOW_UPDATE 的消息时server2,它可以发送更多数据到server2;而且,它必须决定是向客户端发送 WINDOW_UPDATE(因为它与客户端的流控制窗口现在有额外的 16384 个八位字节的空间)还是再等一会儿。例如,它可以发送另外 16384 个八位字节到server2,并且只有在收到第二个 WINDOW_UPDATE 之后server2才能决定向客户端发送一个 WINDOW_UPDATE(更新 16384+16384 个八位字节)。

从上面的例子可以看出,客户端 和 之间的流控制与 和 之间的流控制相关server1但独立。server1server2

您可能还想阅读此答案以讨论有关流量控制策略实现的讨论。

于 2016-11-22T20:25:11.170 回答
1

这取决于啤酒花/中间人的含义。

如果中介位于较低级别(TCP 网关、NAT、交换机等),那么它们对 HTTP/2 是透明的,因为 HTTP/2 流控制是在 HTTP/2 客户端和服务器之间端到端应用的。它们之间的各个跃点可能使用较低级别的流量控制机制。

如果您的中介是 HTTP 代理,那么基本上有两个单独的 HTTP 请求正在进行,每个请求都应用它自己的流量控制。代理应用程序负责连接这些单独的跃点,同时保留流量控制属性。例如,不是一次从第二跳读取整个响应,然后才将其转发到第一跳,而是通过流式传输合适的数据块。

在 HTTP 代理的情况下,您甚至会遇到将 HTTP/1.1 代理到 HTTP/2 的情况,反之亦然。在这些情况下,它们的代理将使用 HTTP/2 流控制机制来保证该跳的流控制,并使用 TCP 流控制来提供对另一跳的流控制。如果协议类型被正确封装在代理应用程序中(这意味着它将提供尊重流控制RequestResponse类型的流操作),那么代理不同协议类型之间的流应该不会太难。

于 2016-11-23T18:27:33.307 回答