为什么 HTTP/2 做多路复用 although tcp 做同样的事情?

Why HTTP/2 does multiplexing altough tcp does same thing?

据我所知,TCP 将消息分解为多个段。那么,为什么要在 HTTP2 上再次进行多路复用呢?两次复用有什么好处?

TCP 不进行多路复用。 TCP 段只是意味着(单个)流数据被分割成可以在 IP 数据包中发送的片段。每个 TCP 段仅用流偏移量(序列号)标识,没有任何有用的方法来标识单独的流。 (我们将忽略很少有用的紧急指针。)

所以要进行多路复用,您需要在 TCP 之上放置一些东西。 HTTP/2 是这样的。

HTTP 和 HTTP/2 都是应用程序级协议,它们必须使用较低级别的协议(如 TCP)才能在 Internet 上进行实际通信。互联网的协议一般是TCP over IP over Ethernet。

看起来像这样:

如您所见,HTTP 位于 TCP 之上。 TCP下面是IP。 Internet 的主要协议之一。 IP 本身处理 switched/multiplexed 的数据包。我认为这就是您可能会认为 TCP 是多路复用的,但事实并非如此。将 TCP 连接想象成一条单车道公路隧道,任何人都无法通过。假设它在每个方向上都有一个单车道。这就是 TCP 连接的样子。一种隧道,您将数据放在一端,数据按照进入的顺序从另一端出来。这就是 TCP。你可以看到上面没有多路复用。然而,TCP 确实提供了一种可靠的连接协议,其他协议可以像 HTTP 一样在其之上构建。可靠性对于 HTTP 至关重要。

HTTP 1.1 只是一个请求响应协议。但如您所知,它不是多路复用的。所以一次只允许一个未完成的请求,并且必须一次发送对每个请求的整个响应。以前,浏览器通过创建多个到服务器的 TCP 连接(隧道)来发出更多请求来绕过该限制。

HTTP 2 实际上再次拆分数据并允许在一个连接上进行多路复用,因此无需创建更多连接。这意味着服务器可以开始为多个请求提供服务并多路复用响应,以便浏览器可以同时开始接收图像、页面和其他资源,而不是一次接收一个。

希望说清楚。

TCP 未被多路复用。 TCP 只是一个有保证的消息流(即重新请求丢失的数据包,并且在这种情况下 TCP 流基本上暂时被阻塞)。

TCP,作为基于数据包的协议,如果更高级别的应用程序协议(例如 HTTP)允许发送多条消息,可以用于多路复用连接。不幸的是 HTTP/1.1 不允许这样做:一旦 HTTP/1.1 消息被发送,在该消息完全返回之前不能在该连接上发送其他消息(忽略支持不佳的流水线概念) .这意味着 HTTP/1.1 基本上是同步的,如果没有使用全部带宽并且其他 HTTP 消息排队,那么它会浪费任何可以在底层 TCP 连接上使用的额外容量。

为了解决这个问题,可以打开更多的 TCP 连接,这基本上允许 HTTP/1.1 到 act 像一个(有限的)多路复用协议。如果网络带宽得到充分利用,那么这些额外的连接将不会增加任何好处 - 事实上存在容量并且其他 TCP 连接没有得到充分利用,这意味着这是有道理的。

因此 HTTP/2 向协议添加多路复用,以允许单个 TCP 连接用于多个正在运行的 HTTP 请求。

它通过将基于文本的 HTTP/1.1 协议更改为二进制的、基于数据包的协议来实现这一点。这些可能看起来像 TCP 数据包,但实际上并不相关(就像说 TCP 类似于 IP 因为它基于数据包是不相关的)。将消息拆分为数据包确实是允许多个消息同时传输的唯一方法。

HTTP/2 还添加了流的概念,以便数据包可以属于不同的请求 - TCP 没有这样的概念 - 这才是真正使 HTTP/2 多路复用的原因。

事实上,因为 TCP 不允许单独的、独立的流(即多路复用),并且因为它是有保证的,这实际上引入了一个新问题,即单个丢弃的 TCP 数据包会阻塞 所有 该连接上的 HTTP/2 流,尽管实际上只有一个流应该受到影响,而其他流应该能够继续进行。在某些情况下,这甚至会使 HTTP/2 变慢。 Google 正在尝试从 TCP 转移到 QUIC 来解决这个问题。

关于 HTTP/2 下多路复用意味着什么的更多详细信息(以及为什么它是一个很好的改进!)在我的回答中: