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

标签 tcp http2 packet frames multiplexing

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

HTTP/2.0 中的多路复用似乎利用单个 TCP 连接同时处理多个/不同的请求,这样我们就可以避免队头阻塞问题。我想知道在感知数据重组方面它是如何工作/与底层 TCP 连接重叠的。

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

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

最佳答案

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

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

我们来看一个例子:一个例子网页需要下载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 是一种有保证的有序协议(protocol),它不知道更高级别的应用程序 (HTTP) 正在使用它做什么,如果 TCP 数据包丢失,这确实会给 HTTP/2 带来一些问题。

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

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

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

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

关于tcp - HTTP/2.0 多路复用如何与 TCP 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60916851/

相关文章:

c++ - 结合多种数据类型来制定数据包

browser - 开始浏览时发送的第一个数据包

c++ - libpcap 是否监视发送的数据包?

networking - Go - 从多个阅读器的 TCP 连接读取数据

networking - RPC 和 TCP 行为

sockets - 32 位 linux 上的同时 tcp/ip 连接数

java - android无法接收从pc发送的所有数据

php - 如何在 PHP 中发送 HTTP/2 POST 请求

nginx - 在 CentOS 7 上支持 HTTP/2 ALPN 的乘客 nginx

http - 为什么说 HTTP2 是二进制协议(protocol)?