【发布时间】:2016-07-30 19:02:16
【问题描述】:
有人能解释一下与 HTTP/2 相关的多路复用及其工作原理吗?
【问题讨论】:
标签: http2
有人能解释一下与 HTTP/2 相关的多路复用及其工作原理吗?
【问题讨论】:
标签: http2
简单地说,多路复用允许您的浏览器在同一连接上一次触发多个请求,并以任意顺序接收返回的请求。
现在是更复杂的答案...
当你加载一个网页时,它会下载 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 * 100ms = 1,000ms 或 1 秒。
为了解决这个问题,浏览器通常会打开多个到 Web 服务器的连接(通常为 6 个)。这意味着浏览器可以同时触发多个请求,这要好得多,但代价是必须设置和管理多个连接的复杂性(这会影响浏览器和服务器)。让我们继续前面的例子,假设有 4 个连接,为了简单起见,假设所有请求都是相等的。在这种情况下,您可以在所有四个连接中拆分请求,因此两个将有 3 个资源要获取,两个将有 2 个资源来获取总共十个资源 (3 + 3 + 2 + 2 = 10)。在这种情况下,最坏的情况是 3 轮次或 300 毫秒 = 0.3 秒——这是一个很好的改进,但这个简单的示例不包括设置这些多个连接的成本,也不包括管理它们的资源影响(我没有去进入这里,因为这个答案已经足够长了,但是设置单独的 TCP 连接确实需要时间和其他资源 - 进行 TCP 连接、HTTPS 握手,然后由于 TCP 启动缓慢而达到全速)。
HTTP/2 允许您在 same 连接上发送多个请求 - 因此您无需按照上述方式打开多个连接。所以你的浏览器可以说“给我这个 CSS 文件。给我那个 JavaScript 文件。给我 image1.jpg。给我 image2.jpg……等等。”充分利用一个单一的连接。这具有明显的性能优势,即不会延迟发送那些等待空闲连接的请求。所有这些请求以(几乎)并行的方式通过 Internet 到达服务器。服务器响应每个人,然后他们开始返回。事实上,它甚至比这更强大,因为 Web 服务器可以以任何感觉的顺序响应它们并以不同的顺序发送回文件,甚至将请求的每个文件分解成碎片并将文件混合在一起。这具有第二个好处,即一个繁重的请求不会阻塞所有其他后续请求(称为head of line blocking 问题)。然后,Web 浏览器的任务是将所有部分重新组合在一起。在最好的情况下(假设没有带宽限制 - 见下文),如果所有 10 个请求几乎同时触发,并由服务器立即响应,这意味着您基本上有一个往返或 100 毫秒或 0.1 秒,下载所有 10 个资源。这没有 HTTP/1.1 的多个连接的缺点!随着每个网站上资源的增长,这也更具可扩展性(目前浏览器在 HTTP/1.1 下最多可打开 6 个并行连接,但随着网站变得更加复杂,这是否应该增长?)。
This diagram 显示差异,还有一个animated version too。
注意:HTTP/1.1 确实有pipelining 的概念,它也允许一次发送多个请求。然而,它们仍然必须按照被请求的顺序全部返回,因此远不及 HTTP/2,即使在概念上是相似的。更不用说浏览器和服务器对它的支持太差了,以至于很少使用它。
下面 cmets 中强调的一件事是带宽对我们的影响。当然,您的 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 连接中的多个响应。因此,与 DNS 查找和握手相关的工作量被保存在来自同一服务器的文件中。
复杂/详细的答案:
查看@BazzaDP 提供的答案。
【讨论】: