HTTP/2.0 多路复用如何与 TCP 一起工作?

How does HTTP/2.0 multiplexing work with TCP?

我不是专业的网络工程师,所以我希望我的问题不会显得含糊或幼稚。

HTTP/2.0 中的多路复用似乎为 multiple/different 请求并发使用单个 TCP 连接,因此我们避免了队头阻塞问题。我想知道如何 works/overlaps 与基础 TCP 连接在感知数据中 重组

TCP 还确保在接收方接收到的数据 (D) 被重建,即使是构成 D 的数据包收到乱序(或丢失),以便在接收方重新构建 D,然后将其交给接收方应用。

我的问题是:HTTP/2.0 中帧的概念如何适合 over/with TCP 数据包重组以在接收方构成整个消息?哪个先发生?或者,帧和数据包之间存在什么样的映射(一对一、一对多等)?简而言之,它们是如何协同工作的?

一系列HTTP/2帧,属于同一个流或不同的流都没有关系,它只是一系列字节。

TCP 不解释这些字节。 TCP 发送方只是将字节打包到 TCP 帧中并一起发送。 TCP 接收器接收 TCP 帧并重新组合恰好形成一系列 HTTP/2 帧的字节。

TCP 和 HTTP/2 并没有真正一起工作,因为 TCP 不知道它正在传输什么——它只是一系列不透明的字节。

因此,TCP 帧和 HTTP/2 帧之间没有映射。

考虑到在大多数情况下 HTTP/2 是加密的,所以你有 TCP 传输不透明的字节,这些字节恰好是 TLS 帧字节(可能是碎片化的 - 即一个 TCP 帧可能包含 1.5 个 TLS 帧和剩余的 TLS 帧字节在后续的 TCP 帧中);每个 TLS 帧都包含不透明字节,这些字节恰好是 HTTP/2 帧字节(也可能是碎片)。

HTTP/2 数据包作为一个或多个 TCP 数据包发送。与 TCP 数据包最终作为 IP 数据包(或数据报)发送的方式相同。

这确实意味着即使 HTTP/2 在应用层 (HTTP) 具有多路复用,但它在传输层 (TCP) 没有真正独立的流,HTTP/2 的一个问题是我们刚刚将线头 (HOL) 阻塞问题从 HTTP 层移到了 TCP 层。

我们来看一个例子:一个例子网页需要下载10张图片才能显示。

在 HTTP/1.1 下,浏览器会打开一个 TCP 连接,触发第一个请求,然后由于无法使用该 TCP 连接发出后续请求而卡住。尽管事实上 TCP 连接在收到响应之前什么都不做,并且在 TCP 层没有任何东西阻止它。这纯粹是一个 HTTP 限制,主要是因为 HTTP/1 是基于文本的,所以不可能混淆请求位。 HTTP/1.1 确实有 HTTP 流水线的概念,允许发送后续请求,但它们仍然必须按顺序返回。而且它得到的支持很差。相反,作为一种解决方法,浏览器打开了多个连接(通常为 6 个),但这也有很多缺点(创建速度慢、跟上速度并且不可能对它们进行优先级排序)。

HTTP/2 允许这些后续请求在同一个 TCP 连接上发送,然后以任何顺序接收所有请求的位并将它们拼凑在一起进行处理。所以请求的第一张图片实际上可能是最后收到的。这对于慢速连接(发送延迟占总时间的很大一部分)或服务器可能需要一段时间处理某些请求(与其他请求相比)(例如,如果必须从磁盘获取第一张图像但第二个已经在缓存中可用,那么为什么不使用连接发送第二个图像)。这就是 HTTP/2 通常比 HTTP/1.1 更快更好的原因 - 因为它更好地使用 TCP 连接并且不那么浪费。

但是,由于 TCP 是一种有保证的有序协议,它不知道更高级别的应用程序 (HTTP) 正在使用它做什么,这确实会给 HTTP/2 带来一些问题,如果 TCP数据包丢失。

假设这 10 张图片都按顺序返回。但是第一张图片中的一个数据包丢失了。理论上,如果HTTP/2真的是由独立的流组成,浏览器可以显示最后9张图片,然后重新请求丢失的TCP数据包,然后显示第一张图片。相反,在 TCP 让上层 HTTP 知道哪些消息已收到之前,所有 10 个图像都被等待重新发送丢失的 TCP 数据包。

因此,在有损环境中,HTTP/2 的性能明显低于 HTTP/1.1,具有 6 个连接。

这在创建 HTTP/2 时是众所周知的,但在大多数情况下,HTTP/2 速度更快,因此他们无论如何都会发布它,直到他们能够解决该问题。

HTTP/3 希望解决剩下的这个问题。它通过从 TCP 转移到一个名为 QUIC 的新协议来实现这一点,该协议与 TCP 不同,该协议采用内置多路复用的思想。 QUIC 建立在 UDP 之上,而不是尝试创建一个全新的低级协议,因为它得到了很好的支持。但是 QUIC 非常复杂,需要一段时间才能实现,这就是为什么他们没有坚持 HTTP/2 拥有它,而是发布了他们拥有的东西作为沿途的一步。