多路复用在 HTTP/2中意味着什么

谁能解释一下与 HTTP/2相关的多路复用以及它是如何工作的?

59386 次浏览

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

现在来回答一个更复杂的问题。

当你加载一个网页,它下载的 HTML 页面,它看到它需要一些 CSS,一些 JavaScript,一个图像的负载... 等等。

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

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

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

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

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

此图 显示了差异,并且有一个 还有动画版

注意: HTTP/1.1确实有 流水线的概念,它也允许一次发送多个请求。然而,它们仍然必须被返回,以便它们被请求,整体而言,所以远不及 HTTP/2好,即使它们在概念上是相似的。更不用说浏览器和服务器对它的支持如此之差,以至于它很少被使用。

下面的评论强调了一件事,那就是带宽是如何影响我们的。当然,您的 Internet 连接受到下载量的限制,而 HTTP/2并没有解决这个问题。因此,如果上面例子中讨论的10个资源都是大量打印质量的图像,那么它们的下载速度仍然会很慢。然而,对于大多数 Web 浏览器来说,带宽问题比延迟问题要小。因此,如果这十个资源是小项目(特别是像 CSS 和 JavaScript 这样的文本资源,它们可以被压缩成很小的文本) ,就像在网站上非常常见的那样,那么带宽并不是真正的问题——问题通常是资源的绝对数量,HTTP/2看起来就是要解决这个问题。这也是为什么在 HTTP/1.1中使用连接作为另一种解决方案的原因,例如,所有的 CSS 通常被连接到一个文件中: 下载的 CSS 数量是相同的,但是作为一个资源使用它会带来巨大的性能好处(尽管 HTTP/2的情况不是这样,事实上有些人说连接应该是一个 HTTP/2下的反模式——尽管也有人反对完全废除它)。

举个现实生活中的例子: 假设你必须从一家商店订购10件送货上门的物品:

  • 只有一个连接的 HTTP/1.1意味着您必须一次订购一个,并且在最后一个到达之前不能订购下一个商品。你可以理解,要花几个星期才能把所有东西都看完。

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

  • 使用流水线的 HTTP/1.1意味着您可以一个接一个地请求所有10个项目,而不需要等待,但是它们都会按照您要求的特定顺序到达。如果一件商品没有库存,那么你必须等到那之后才能得到你订购的商品——即使那些后来的商品实际上是有库存的!这样稍微好一点,但仍然容易延误,而且我们假设大多数商店不支持这种订购方式。

  • HTTP/2意味着您可以按照任何特定的顺序订购您的商品,而不会有任何延迟(类似于上述)。商店会在他们准备好的时候发货,所以他们可能会按照你要求的不同顺序到达,他们甚至可能会分割物品,这样一些订单的部分会先到达(比上面的要好)。最终,这应该意味着你1)总体上得到一切更快,2)可以开始工作的每一个项目,因为它到达(“哦,这不是很好,因为我认为它会是,所以我可能想要订购其他东西或代替”)。

当然,你仍然受到邮递员面包车的大小(带宽)的限制,所以如果那一天的包裹满了,他们可能不得不把一些包裹留在分拣办公室,直到第二天,但是与实际上把订单往返发送的延迟相比,这很少是一个问题。大多数的网页浏览涉及到来回发送小信件,而不是笨重的包裹。

希望能帮上忙。

简单答案(来源) :

多路复用意味着您的浏览器可以发送多个请求并接收多个“绑定”到单个 TCP 连接的响应。因此,与 DNS 查找和握手相关的工作负载被保存为来自同一服务器的文件。

复杂/详细答案:

看看@BazzaDP 提供的答案。

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

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

HTTP1 VS HTTP2 interchange process

请求多路复用

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

enter image description here

由于@Juanma Menendez 的回答是正确的,而他的图表是令人困惑的,所以我决定对它进行改进,澄清多路复用和流水线之间的区别,这两个概念常常混为一谈。

流水线(HTTP/1.1)

通过 一样 HTTP 连接发送多个请求。按照相同的顺序接收响应。如果第一个响应需要很长时间,其他的响应必须排队等待。与 CPU 流水线类似,其中一条指令被获取,而另一条指令被解码。多个指令同时在飞行,但它们的顺序保持不变。

多路复用(HTTP/2)

通过 一样 HTTP 连接发送多个请求。以任意顺序接收响应。没有必要等待一个缓慢的反应,阻碍了其他人。类似于现代 CPU 中的无序指令执行。

希望改进后的图像能够澄清其中的区别:

Standard HTTP/1.1 flow/Pipelining/Multiplexing