HTTP/2 中的多路复用是什么意思

What does multiplexing mean in HTTP/2

有人可以解释与 HTTP/2 相关的多路复用及其工作原理吗?

简而言之,多路复用允许您的浏览器在同一连接上同时发出多个请求,并以任何顺序接收请求。

现在要回答更复杂的问题...

当您加载网页时,它会下载 HTML 页面,它会发现它需要一些 CSS、一些 JavaScript、大量图像...等等

在 HTTP/1.1 下,您在 HTTP/1.1 连接上一次只能下载其中一个。所以您的浏览器会下载 HTML,然后它会请求 CSS 文件。当它返回时,它要求 JavaScript 文件。当它返回时,它要求第一个图像文件...等。HTTP/1.1 基本上是同步的 - 一旦您发送请求,您就会卡住,直到您得到响应。这意味着大多数时候浏览器并没有做太多事情,因为它已经发出请求,正在等待响应,然后发出另一个请求,然后正在等待响应......等等。当然复杂的网站许多 JavaScript 确实需要浏览器进行大量处理,但这取决于正在下载的 JavaScript 因此,至少在开始时,延迟会继承到 HTTP/1.1 确实会导致问题。通常服务器也不会做很多事情(至少每个请求 - 当然它们会增加繁忙的站点),因为它应该几乎立即响应静态资源(如 CSS、JavaScript、图像,字体...等),希望即使对于动态请求(需要数据库调用等)也不会太长。

因此,当今网络上的主要问题之一是在浏览器和服务器之间发送请求时的网络延迟。它可能只有几十或几百毫秒,这可能看起来并不多,但它们加起来通常是网络浏览中最慢的部分 - 特别是当网站变得越来越复杂并且需要额外的资源(因为它们正在获得)和互联网访问时越来越多地通过移动设备(延迟比宽带慢)。

举个例子,假设在 HTML 本身加载后,您的网页需要加载 10 个资源(按照今天的标准,这是一个非常小的网站,因为 100 多个资源很常见,但我们将保持简单并使用此示例)。假设每个请求需要 100 毫秒通过 Internet 传输到 Web 服务器并返回,并且两端的处理时间可以忽略不计(为简单起见,我们假设此示例为 0)。由于您必须一次发送每个资源并等待响应,因此下载整个站点需要 10 * 100 毫秒 = 1,000 毫秒或 1 秒。

为了解决这个问题,浏览器通常会打开多个到 Web 服务器的连接(通常为 6 个)。这意味着浏览器可以同时触发多个请求,这要好得多,但代价是必须设置和管理多个连接的复杂性(这会影响浏览器和服务器)。让我们继续前面的例子,假设有 4 个连接,为了简单起见,我们假设所有请求都是平等的。在这种情况下,您可以将请求拆分到所有四个连接中,因此两个连接将获得 3 个资源,两个连接将获得 2 个资源以总共获得十个资源 (3 + 3 + 2 + 2 = 10)。在那种情况下,最坏的情况是 3 轮时间或 300 毫秒 = 0.3 秒 - 一个很好的改进,但这个简单的例子不包括设置这些多个连接的成本,也不包括管理它们的资源影响(我没有去进入这里,因为这个答案已经足够长了,但是建立单独的 TCP 连接确实需要时间和其他资源——进行 TCP 连接、HTTPS 握手,然后由于 TCP 启动慢而达到全速。

HTTP/2 允许您在 相同的 连接上发送多个请求 - 因此您不需要像上面那样打开多个连接。所以你的浏览器可以说“给我这个 CSS 文件。给我那个 JavaScript 文件。给我 image1.jpg。给我 image2.jpg... 等等。”充分利用单一连接。这具有不延迟发送那些等待空闲连接的请求的明显性能优势。所有这些请求都(几乎)并行地通过 Internet 到达服务器。服务器响应每一个,然后他们开始返回。事实上,它比这更强大,因为 Web 服务器可以按照感觉的任何顺序响应它们,并以不同的顺序发回文件,甚至可以将请求的每个文件分解成多个部分并将文件混合在一起。这样做的第二个好处是一个繁重的请求不会阻塞所有其他后续请求(称为 head of line blocking 问题)。然后,网络浏览器的任务是将所有部分重新组合在一起。在最好的情况下(假设没有带宽限制 - 见下文),如果所有 10 个请求几乎同时被并行触发,并且服务器立即响应,这意味着你基本上有一个往返或 100 毫秒或 0.1 秒,到下载所有 10 个资源。这有 none 多个连接对 HTTP/1.1 的缺点!随着每个网站上资源的增长,这也更具可扩展性(目前浏览器在 HTTP/1.1 下最多打开 6 个并行连接,但随着网站变得更复杂,它应该增加吗?)。

This diagram shows the differences, and there is an animated version too.

注意:HTTP/1.1 确实有 pipelining 的概念,它也允许一次发送多个请求。然而,它们仍然必须按要求完整地返回,因此远不及 HTTP/2,即使在概念上它是相似的。更不用说浏览器和服务器对它的支持太差以至于很少使用。

下面评论中强调的一件事是带宽如何影响我们。当然,您的 Internet 连接受到您可以下载的数量的限制,HTTP/2 没有解决这个问题。因此,如果上述示例中讨论的 10 个资源都是大量打印质量的图像,那么它们的下载速度仍然很慢。但是,对于大多数 Web 浏览器而言,带宽问题不如延迟问题大。因此,如果这十个资源是小项目(特别是像 CSS 和 JavaScript 这样的文本资源,可以压缩成很小的),这在网站上很常见,那么带宽就不是真正的问题 - 它是大量的资源通常是问题所在,HTTP/2 希望解决这个问题。这也是为什么在 HTTP/1.1 中使用连接作为另一种解决方法的原因,例如,所有 CSS 通常连接到一个文件中:下载的 CSS 的数量是相同的,但是将其作为一种资源来执行会带来巨大的性能优势(尽管 HTTP/2 的性能优势较小,实际上有人说串联应该是 anti-pattern under HTTP/2 - 尽管也有人反对完全取消它)。

举一个现实世界的例子:假设您必须从商店订购 10 件商品才能送货上门:

  • HTTP/1.1 与一个连接意味着您必须一次订购一个,并且在最后一个到达之前不能订购下一个项目。你可以理解,完成所有事情需要数周时间。

  • HTTP/1.1 具有多个连接意味着您可以同时拥有(有限)数量的独立订单。

  • HTTP/1.1 使用流水线意味着您可以一个接一个地要求所有 10 件物品而无需等待,但随后它们都会按照您要求的特定顺序到达。如果一件商品缺货,那么您必须等待,然后才能收到您订购的商品 - 即使后来的商品实际上有货!这样好一点,但仍然有延迟,而且大多数商店都不支持这种订购方式。

  • HTTP/2 意味着您可以按任何特定顺序订购您的商品 - 没有任何延迟(与上述类似)。商店会在它们准备好时发货,因此它们可能会以与您要求的不同的顺序到达,它们甚至可能会拆分物品,因此订单中的某些部分会先到达(比上面更好)。最终这应该意味着您 1) 总体上更快地完成所有事情,并且 2) 可以在每个项目到达时开始处理(“哦,这不像我想象的那么好,所以我可能也想订购其他东西或者代替” ).

当然,您仍然受到邮递员货车大小(带宽)的限制,因此他们可能不得不将一些包裹留在分拣办公室,直到第二天才满载,但是与实际发送和返回订单的延迟相比,这几乎不是问题。大多数网页浏览都涉及来回发送小字母,而不是大包裹。

希望对您有所帮助。

简单答案 (Source) :

多路复用意味着您的浏览器可以向单个 TCP 连接发送多个请求并接收多个响应 "bundled"。因此,为来自同一服务器的文件节省了与 DNS 查找和握手相关的工作量。

Complex/Detailed 答案:

看看@BazzaDP 提供的答案。

HTTP 2.0 中的多路复用是浏览器和服务器之间的一种关系,它使用单个连接并行传送多个请求和响应,在此过程中创建许多单独的帧。

多路复用摆脱了严格的请求-响应语义,并支持一对多或多对多关系。

请求复用

HTTP/2 可以通过单个 TCP 连接并行发送多个数据请求。这是 HTTP/2 协议的最高级功能,因为它允许您从一台服务器异步下载 Web 文件。大多数现代浏览器都将 TCP 连接限制在一台服务器上。这减少了额外的往返时间 (RTT),使您的网站在没有任何优化的情况下加载更快,并且不需要域分片。

由于@Juanma Menendez 的答案是正确的,而他的图表令人困惑,我决定对其进行改进,阐明多路复用和流水线之间的区别,这些概念经常被混淆。

流水线处理 (HTTP/1.1)

多个请求通过同一个 HTTP 连接发送。以相同的顺序接收响应。如果第一个响应需要很多时间,其他响应必须排队等候。类似于 CPU 流水线,其中一条指令被提取,而另一条指令正在被解码。多个指令同时运行,但它们的顺序被保留。

多路复用 (HTTP/2)

多个请求通过同一个 HTTP 连接发送。以任意顺序接收响应。无需等待阻碍他人的缓慢响应。类似于现代 CPU 中的 out-of-order 指令执行。

希望改进后的图像能说明差异: