微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么使用 HTTP/2 的 app 只能建立一个 TCP 连接?

如何解决为什么使用 HTTP/2 的 app 只能建立一个 TCP 连接?

我了解 HTTP/2 多路复用解决了 HTTP/1.1 中的队头阻塞问题。但是,TCP 协议中仍然存在队头阻塞。即使在应用层同时发送请求,消息仍然需要一对一的TCP连接发送。
我的问题是为什么使用 HTTP/2 的应用程序不建立多个 TCP 连接,这样传输层(TCP 协议)就不会限制 HTTP/2 多路复用?
我知道在 UDP(QUIC) 上使用 HTTP/2 可以避免这个问题。在这文章中,我将讨论基于 TCP 的 HTTP/2。
如果应用程序确实建立了多个 TCP 连接(以防我不知道这个实现已经存在)。请求如何在所有 TCP 连接之间分配?

解决方法

是的,这是 HTTP/2 的一个已知问题,也是 HTTP/3 旨在通过在同一连接中拥有完全独立的流来解决的问题。为此,他们不能使用 TCP,而必须从头开始构建 TCP 的多路复用版本(称为 QUIC)。

来自 Fastly 的 Hooman Beheshti 做了 a great talk on this 并表明,如果数据丢失始终保持 2%,您最好使用 HTTP/1.1。

那我们该怎么办?根本不使用 HTTP/2 而现在坚持使用 HTTP/1.1?或者,如您所建议的那样,对多个连接使用 HTTP/2。

好吧,首先您需要意识到,在大多数连接上,数据丢失,或者至少是一致的数据丢失实际上是相对罕见的。根据那次谈话,持续 2% 的数据丢失基本上是一个糟糕的连接!数据丢失更加间歇性和突发性(例如,当您退出移动接收功能,然后又重新进入时)。

HTTP/2 发布之前的研究表明,在大多数情况下 HTTP/2 比 HTTP/1.1 更好 - 或者至少有机会更好地实现 HTTP/2 设置更快。

是的,事后看来,HTTP/2 被夸大了,而且与优化良好的 HTTP/1.1 站点相比,其收益通常相对较小。是的,在某些情况下它也可能更糟(特别是如果服务器不正确支持优先级)。但这在发布之前就已为人所知,但总的来说,HTTP/2 更好,值得推荐。

有些情况下,就像你给出的那样,它的表现可能会更糟。如果您的特定应用程序预计损失惨重(我不知道,假设您正在开发一个经常在地下深处的矿井中使用的移动应用程序并且连接来来去去),那么也许不要使用 HTTP/2 并在这种情况下使用更好的协议(可能包括 HTTP/1.1)。但是对于一般的网页浏览,HTTP/2 在大多数情况下可能更好。

那么为什么我们不使用具有多个连接的 HTTP/2 呢?

HTTP/2 的主要好处是更好地利用了单一连接。 HTTP 连接设置(尤其是 HTTPS)很昂贵 - 您需要 TCP 握手、TLS 握手,然后才能发出请求。即使在那之后,您也必须通过 TCP 慢启动才能使连接达到全速。如果连接没有得到充分利用,那么它会再次变慢,您需要再次重复这种慢启动方法。

使用单个连接意味着您只需支付一次设置费用,并且意味着您不太可能未充分利用该连接,因此回退到较慢的连接速度,并且必须通过 TCP 慢启动再次。此外,您可以对单个连接上的请求进行跨优先级排序。如果你有一些关键的 CSS 和一些较低优先级的图像或异步 JavaScript 也在运行中,服务器可以优先考虑 CSS 并使用带宽并阻止图像和异步 JavaScript(尽管并非所有服务器都很好地实现了 HTTP/2 优先级) )。使用独立的连接,不同请求之间的优先级是不可能的,因此您最终会低效使用带宽。

然而,有些人建议,对于有损连接,即使在 HTTP/2 下,我们也应该切换回两个甚至更多连接(请参阅 22-minute point of that above presentation)。

HTTP/2 也是向 HTTP/3 迈出的一步(尽管最初将在 QUIC 上称为 HTTP/2)。向 HTTP/2 的转变是对 Web 核心协议之一的工作方式的一大步和重大改变。从开发人员的角度来看,在 HTTP/2 下不需要捆绑太多(尽管完全删除捆绑太远)的心态转变是 HTTP/2 随附的,并且在 HTTP/3 下不会改变. HTTP/2 于 2015 年签署,它的继任者 HTTP/3 用了 6 年的时间来解决这个问题,它是一个复杂得多的协议,最初为这种复杂性带来的好处要少得多。为您的服务器运行 HTTP/3 并以最佳方式对其进行优化会困难得多。

因此,拖延希望通过 HTTP/3 交付的完整解决方案,而不是继续使用 HTTP/2,将是错误的选择。使用多个 HTTP/2 连接也有缺点。

希望能回答您的问题。

,

我的问题是为什么使用 HTTP/2 的应用程序不建立多个 TCP 连接,这样传输层(TCP 协议)就不会限制 HTTP/2 复用?

这正是您在 HTTP/1.1 中已经可以通过设置几个持久并行连接来依次请求多个文件的方法。

但是您建立的每个连接都需要 TCP 握手才能建立。假设该站点通过 HTTPS 运行,除此之外还需要 TLS 握手。这是大张旗鼓。

HTTP/2 只需要一次 TCP+TLS 握手就避免了这种大肆宣传,但正如您所提到的,它仍然是应用层上的“假装”并行性。因此,如果您通过两个流传输并且流 1 出现问题,则流 2 无法继续传输,直到 TCP 解决了流 1 的问题。 QUIC 在传输层上提供对并行流的支持,因此它不会遇到相同的队头阻塞问题。

tl;dr – 如果这太抽象或太多,我已经对 HTTP/1.1、HTTP/2 和 HTTP/3(使用 QUIC)如何处理这个问题进行了动画比较问题 here

,

你说得对,这是 HTTP/2 和 TCP 的问题。问题是,TCP(根据最新的 RFC)几乎不能支持多路复用。这就是 QUIC 发挥作用的地方,也是它受到如此多关注的原因之一。通过为每个感兴趣的 HTTP 资源打开多个 TCP 连接来与 TCP 进行多路复用可能是一个有效的解决方案,但存在一些问题。

  1. 建立多个 TCP 连接的开销很大(它们都需要与服务器建立连接,例如 SYN/SYN-ACK/ACK)。
  2. 此外,每个此类连接都将从初始 CWND 值(通常为 10)开始,因此传输最终可能会变慢。
  3. 我认为这很重要:您可能需要所有资源才能成功加载网络请求(有意义)。例如,考虑打开一个包含一些 HTML、CSS 和 JS 文件的网页。您可以打开 3 个单独的连接并单独请求所有这些,但在与页面进行任何有意义的交互之前,您可能确实需要所有三个文件。
  4. 如果 3. 由于某种原因不适用,您将不得不在应用层小心,因为资源可能以不同的顺序到达。

但是,有一个例外,根据您使用的浏览器,我观察到了不同的行为。这个例外是如果网站有网站图标。当向服务器发出初始请求时,您可能需要所有与网页相关的材料,但您并不真正关心是否收到小标签预览图标(收藏夹图标),并且您不希望任何损失阻止您与页面交互,如果这是唯一缺少的东西。

我看到我的 Firefox 有时会打开一个新连接来下载收藏夹图标,而 chrome 似乎在同一连接上下载该连接和页面材料。实际上,我认为这只是一种实现选择,因为这是我能想到的唯一可以使用它的边缘情况,但同样,收藏夹图标太小,不太可能产生影响。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?