原文链接:https://www.smashingmagazine.com/2021/08/http3-performance-improvements-part2/ 作者亲自操刀的系列文章,英文的,英文水平不错的同学请移步,毕竟我的英文水平比较low,可能翻译的不到位(尤其是这篇发展哪儿,我都感觉读起来怪怪的)

摘要

经过近五年的开发,新的 HTTP/3协议已接近最终形式。让我们仔细研究一下 HTTP/3、拥塞控制、线头阻塞和0-rTT 连接设置的性能改进。

欢迎回到关于新的 HTTP/3协议的本系列。在第1部分中,我们研究了为什么我们确切地需要 HTTP/3和底层 QUIC 协议,以及它们的主要新特性是什么。

在第二部分中,我们将放大 QUIC 和 HTTP/3为 Web 页面加载带来的性能改进。然而,我们也会对这些新特性在实践中可能产生的影响表示怀疑。

正如我们将看到的,QUIC 和 HTTP/3确实有很大的 web 性能潜力,但主要是针对低速网络上的用户。如果您的普通访问者使用的是快速有线或蜂窝网络,那么他们可能不会从新协议中受益太多。然而,请注意,即使在国家和地区,通常快速上传,最慢的1% ,甚至10% 的观众(所谓的第99或第90百分位)仍然有可能获得很多。这是因为 HTTP/3和 QUIC 主要帮助处理在今天的互联网上可能出现的一些不常见但是潜在影响很大的问题。

这一部分比第一部分稍微技术一些,尽管它将大部分真正深奥的东西卸载给外部资源,重点解释为什么这些东西对普通的 web 开发人员很重要。

  • 第1部分: HTTP/3历史记录和核心概念:本文针对 HTTP/3和一般协议的新手,主要讨论基础知识
  • 第2部分: HTTP/3性能特性 :这一个更深入和技术性。人们谁已经知道的基本知识可以从这里开始
  • 第3部分: 实用 HTTP/3部署选项:本系列的第三篇文章解释了自己部署和测试 HTTP/3所涉及的挑战。它详细说明了如何以及是否应该更改您的网页和资源

速度入门

讨论性能和“速度”可能很快变得复杂,因为许多潜在的方面导致网页加载“缓慢”。因为我们在这里讨论的是网络协议,所以我们将主要关注网络方面,其中有两个最重要的方面: 延迟和带宽。

延迟可以粗略地定义为从点 A (比如说,客户端)发送数据包到点 B (服务器)所需的时间。它在物理上受到光速的限制,实际上也受到信号在电线或空气中传播速度的限制。这意味着延迟通常取决于 A 和 B 之间的物理的、现实世界的距离。

在地球上,这意味着典型的延迟在概念上很小,大约在10到200毫秒之间。但是,这只是一种方式: 对数据包的响应也需要返回。双向延迟通常称为往返时间(RTT)。

由于诸如拥塞控制之类的特性(见下文) ,我们通常需要很多次往返才能加载一个文件。因此,即使小于50毫秒的低延迟也可能导致相当大的延迟。这是内容传递网络(CDN)存在的主要原因之一: 它们将服务器物理地放置在离最终用户更近的地方,以便尽可能减少延迟,从而减少延迟。

因此,可以粗略地说,带宽是可以同时发送的数据包的数量。这有点难以解释,因为它取决于媒体的物理属性(例如,无线电波的使用频率) ,网络上用户的数量,以及互连不同子网的设备(因为它们通常每秒只能处理一定数量的数据包)。

一个常用的比喻是用来输送水的管子。管道的长度是延迟,而管道的宽度是带宽。然而,在互联网上,我们通常有一长串连接的管道,其中一些可能比其他管道更宽(导致所谓的瓶颈在最窄的链接)。因此,点 A 和点 B 之间的端到端带宽经常受到最慢子节的限制。

虽然本文的其余部分不需要完全理解这些概念,但拥有一个共同的高级定义将是有益的。要了解更多信息,我推荐查看 Ilya Grigorik 在他的《高性能浏览器网络》一书中关于延迟和带宽的精彩章节。

拥塞控制

性能的一个方面是关于传输协议如何有效地使用网络的全部(物理)带宽(即每秒可以发送或接收多少个数据包)。这反过来又会影响页面资源的下载速度。有些人声称 QUIC 在某种程度上比 TCP 做得更好,但事实并非如此。

你知道吗?
例如,TCP 连接不会仅仅开始以全带宽发送数据,因为这可能导致网络超载(或拥塞)。这是因为,正如我们所说,每个网络链路每秒只能(物理地)处理一定数量的数据。如果再给它更多的信息,除了丢弃过多的数据包之外别无选择,这将导致包丢失
对于 TCP 这样的可靠协议,从数据包丢失中恢复的唯一方法是重新传输数据的一个新副本,这需要一个往返过程。特别是在高延迟网络上(比如,超过50毫秒的 RTT) ,数据包丢失会严重影响性能

另一个问题是,我们不知道预先最大带宽将是多少。它通常取决于端到端连接中的某个瓶颈,但是我们无法预测或知道它将在哪里。互联网也没有机制(尚未)信号连接能力回端点。

此外,即使我们知道可用的物理带宽,也不意味着我们可以自己使用所有的带宽。几个用户通常并发地活跃在一个网络上,每个用户都需要公平分享可用带宽。

因此,连接不知道它能够安全或公平地预先使用多少带宽,而且这个带宽可以随着用户加入、离开和使用网络而改变。为了解决这个问题,TCP 将不断尝试使用一种称为拥塞控制的机制来发现可用的带宽。

在连接开始时,它只发送几个数据包(实际上,范围在10到100个数据包之间,或者大约14到140KB 的数据) ,然后等待一个往返过程,直到接收方发回对这些数据包的确认。如果它们都得到了确认,这意味着网络可以处理发送速率,我们可以尝试重复这个过程,但是需要更多的数据(实际上,每次迭代发送速率通常会加倍)。

这样,发送速率会持续增长,直到有些数据包没有得到确认(这表明数据包丢失和拥塞控制)。这第一阶段通常被称为“缓慢的开始”。在检测到数据包丢失后,TCP 降低了发送速率,并且(在一段时间后)开始再次提高发送速率,尽管增量要小得多。这种先减后增的逻辑在以后的每次丢包时都会重复。最终,这意味着 TCP 将不断努力实现其理想的、公平的带宽共享。该机制如图1所示。

这是对拥塞控制的一种极其简单的解释。在实际应用中,还有许多其他因素在起作用,如缓冲区膨胀、由于拥塞导致的 RTT 波动,以及多个并发发送方需要获得公平的带宽份额等。因此,许多不同的拥塞控制算法存在,并且大量仍在发明今天,没有执行最佳的所有情况。

虽然 TCP 的拥塞控制使其更加健壮,但这也意味着它需要一段时间才能达到最佳的发送速率,这取决于 rTT 和实际可用的带宽。对于网页加载来说,这种缓慢启动的方法也会影响指标,比如第一次满意的绘制,因为只有少量的数据(几十到几百 KB)可以在前几次往返中传输。(您可能已经听到了将关键数据保持在14KB 以下的建议。)

因此,选择更积极的方法可以在高带宽和高延迟网络上获得更好的结果,特别是如果您不关心偶尔的数据包丢失的话。这就是我再次看到许多关于 QUIC 工作原理的误解的地方。

正如第1部分所讨论的,理论上,QUIC 遭受的包丢失(和相关的行首(HOL)阻塞)较少,因为它独立地处理每个资源的字节流上的包丢失。此外,QUIC 运行在用户数据报协议(UDP)上,与 TCP 不同,UDP 没有内置拥塞控制功能,它允许你尝试以任何你想要的速率发送,并且不会重新传输丢失的数据。

这导致许多文章声称 QUIC 也不使用拥塞控制,QUIC 可以开始通过 UDP 以更高的速率发送数据(依赖于去除 HOL 阻塞来处理数据包丢失) ,这就是为什么 QUIC 比 TCP 快得多。

事实上,没有比这更离谱的了: QUIC 实际上使用了与 TCP 非常相似的带宽管理技术。它也以较低的发送速率开始,并随着时间的推移而增长,使用确认作为衡量网络容量的关键机制。这是因为 QUIC 需要可靠才能对 HTTP 之类的东西有用,因为它需要对其他 QUIC (和 TCP!)公平因为它的 HOL 阻塞去除实际上并不能很好地防止数据包丢失(正如我们将在下面看到的)。

然而,这并不意味着 QUIC 不能比 TCP 更聪明地管理带宽。这主要是因为 QUIC 比 TCP 更灵活,更容易演化。正如我们所说,拥塞控制算法在今天仍然在不断发展,我们可能需要,例如,调整一些东西,以获得最大限度的5G。

然而,TCP 通常是在操作系统(OS’)内核中实现的,操作系统内核是一个安全且受到更多限制的环境,对于大多数操作系统来说,它甚至不是开源的。因此,调优拥塞逻辑通常只由少数开发人员完成,而且进展缓慢。

相比之下,大多数 QUIC 实现目前是在“用户空间”(我们通常运行本地应用程序)中完成的,并且是开源的,显然是为了鼓励更多的开发人员进行实验(例如,Facebook 已经展示了这一点)。

另一个具体的例子是 QUIC 的延迟确认频率扩展方案。默认情况下,QUIC 为每2个接收到的数据包发送一个确认,而这个扩展允许端点确认,例如,每10个数据包。在卫星网络和高带宽网络中,由于降低了传输确认包的开销,因此这种方法具有很大的速度优势。为 TCP 添加这样的扩展需要很长时间才能被采用,而对 QUIC 来说,部署起来要容易得多。

因此,我们可以期待 QUIC 的灵活性将导致更多的实验和更好的拥塞控制算法随着时间的推移,这反过来也可以回移植到 TCP 来改进它。

你知道吗?
2009年QUIC 恢复 RFC的裁决指定使用 NewReno 拥塞控制算法有点过时了。在实践中不再广泛使用。那么,为什么它在 QUIC RFC 中?第一个原因是当 QUIC 启动时,NewReno 是最新的拥塞控制算法,它本身已经标准化了。更高级的算法,如 BBR 和 CUBIC,要么仍然没有标准化,要么最近变成了 RFC

第二个原因是,新雷诺是一个相对简单的设置。因为这些算法需要一些调整来处理 QUIC 与 TCP 的差异,所以用一个更简单的算法来解释这些变化更容易。因此,RFC 9002应该更多地被理解为“如何使拥塞控制算法适应 QUIC”,而不是“这是 QUIC 应该使用的东西”。实际上,大多数生产级 QUIC 实现都对两者进行了定制实现Cubic 和 BBR.

值得重复的是,拥塞控制算法不是 TCP 或 QUIC 特定的,它们可以被任何一种协议使用,并且希望 QUIC 的进步最终也能找到到 TCP 协议栈的方法

你知道吗?
请注意,拥塞控制旁边是一个相关的概念,称为流量控制。这两个特性在 TCP 中经常被混淆,因为它们都被称为使用“ TCP 窗口”,尽管实际上有两个窗口: 拥塞窗口和 TCP 接收窗口。然而,对于我们感兴趣的网页加载用例来说,流量控制的作用要小得多,所以我们在这里跳过它。更深入的信息是可用的。(译者注,这三个链接确实很奇怪,但原文确实是在短短一句话中放了三个不同链接)

这一切意味着什么?

QUIC 仍然受到物理定律的约束,需要对互联网上的其他发送者友好。这意味着它不会神奇地比 TCP 更快地下载你的网站资源。然而,QUIC 的灵活性意味着尝试新的拥塞控制算法将变得更加容易,这将在未来为 TCP 和 QUIC 带来改进。

0-RTT 连接设置

第二个性能方面是关于在新连接上发送有用的 HTTP 数据(比如页面资源)之前需要多少次往返。有些人声称 QUIC 比 TCP + TLS 来回快两到三次,但我们将看到它实际上只有一次。

你知道吗?
我们已经在第一部分说过了, 在 HTTP 请求和响应可以交换之前,连接通常执行一次(TCP)或两次(TCP + TLS)握手。这些握手交换客户端和服务器都需要知道的初始参数,以便(例如)加密数据
正如您在下面的图2中看到的,每次握手握手至少需要一次往返才能完成(TCP + TLS 1.3,(b)) ,有时需要两次(TLS 1.2和之前的(a))。这是低效的,因为我们需要少两次往返
在我们可以发送第一个 HTTP 请求之前,我们需要等待握手等待时间(开销) ,这意味着要等待至少三个来回,才能收到第一个 HTTP 响应数据(返回的红色箭头)。在低速网络上,这意味着100到200毫秒的开销

您可能想知道为什么 TCP + TLS 握手不能简单地组合在一起,在同一个往返过程中完成。虽然这在概念上是可能的(QUIC 就是这样做的) ,但最初的设计并不是这样的,因为我们需要能够使用 TCP,无论是否在顶部使用 TLS。换句话说,TCP 根本不支持在握手过程中发送非 TCP 内容。在 TCP Fast Open 扩展中已经尝试过添加这个功能; 然而,正如第1部分中所讨论的,事实证明这很难大规模部署。

幸运的是,QUIC 的设计从一开始就考虑到了 TLS,因此将传输和密码握手结合在一个机制中。这意味着 QUIC 握手总共只需要一次往返,比 TCP + TLS 1.3少一次往返(参见上面的图2c)。

您可能会感到困惑,因为您可能已经读到 QUIC 比 TCP 快两到三个来回,而不仅仅是一个来回。这是因为大多数文章只考虑最坏的情况(TCP + TLS 1.2,(a)) ,而没有提到现代的 TCP + TLS 1.3也“只”进行两次往返((b)很少显示)。虽然一次往返的速度提升是不错的,但这并不令人惊讶。特别是在快速网络上(比如说,不到50毫秒的 RTT) ,这几乎不会引起注意,尽管缓慢的网络和到远程服务器的连接会获得更多的利润。

接下来,您可能想知道为什么我们需要等待握手。为什么我们不能在第一次往返时发送 HTTP 请求?这主要是因为,如果我们这样做了,那么第一个请求将发送未加密,可由任何窃听线路,这显然是不大的隐私和安全。因此,在发送第一个 HTTP 请求之前,我们需要等待加密握手完成。是吗?

这就是一个聪明的把戏在实践中使用的地方。我们知道,用户经常在他们第一次访问的很短时间内重新访问网页。因此,我们可以使用最初的加密连接在将来引导第二个连接。简单地说,在第一个连接的生命周期中的某个时候,第一个连接用于在客户机和服务器之间安全地通信新的加密参数。然后,可以使用这些参数从一开始就对第二个连接进行加密,而不必等待完整的 TLS 握手完成。这种方法称为“会话恢复”。

它允许一个强大的优化: 我们现在可以安全地发送我们的第一个 HTTP 请求以及 QUIC/TLS 握手,节省另一个往返行程!至于 TLS 1.3,这有效地消除了 TLS 握手的等待时间。这种方法通常称为0-RTT (当然,HTTP 响应数据开始到达仍然需要一个往返过程)。

会话恢复和0-RTT 都是我经常错误地解释为 QUIC 特定的特性。实际上,这些实际上是 TLS 特性,它们已经以某种形式出现在 TLS 1.2中,现在已经在 TLS 1.3中完全成熟。

换句话说,正如您在下面的图3中看到的,我们也可以通过 TCP (因此也可以通过 HTTP/2甚至 HTTP/1.1)获得这些特性的性能优势!我们看到,即使使用0-RTT,QUIC 仍然只比功能最佳的 TCP + TLS 1.3堆栈快一个来回。QUIC 比图2(a)和图3(f)快三个来回的说法来自于比较图2(a)和图3(f) ,正如我们已经看到的,这是不公平的。

最糟糕的是,当使用0-RTT 时,由于安全问题,QUIC 甚至不能很好地使用所获得的往返行程。为了理解这一点,我们需要理解 TCP 握手存在的原因之一。首先,它允许客户机在发送任何更高层数据之前,确保服务器在给定的 IP 地址上确实可用。

其次,也是至关重要的一点,它允许服务器在发送数据之前确保打开连接的客户端实际上是他们所说的人和地点。如果您还记得我们在第1部分中是如何定义与4元组的连接的,那么您就会知道客户机主要是通过其 IP 地址来识别的。这就是问题所在: IP 地址可能被欺骗!

假设攻击者通过基于 QUIC 0-RTT 的 HTTP 请求一个非常大的文件。然而,他们伪造了他们的 IP 地址,使其看起来像0-RTT 请求来自受害者的计算机。下面的图4显示了这一点。QUIC 服务器无法检测 IP 是否被欺骗,因为这是它从该客户机看到的第一个数据包。

如果服务器只是简单地开始将大文件发送回欺骗的 IP,它可能最终超载受害者的网络带宽(特别是如果攻击者并行执行许多这些虚假请求)。注意,QUIC 响应将被受害者丢弃,因为它不期望传入数据,但这并不重要: 他们的网络仍然需要处理数据包!

这被称为反射或放大攻击,它是黑客执行分布式拒绝服务(DDoS)攻击的重要方式。请注意,在使用 TCP + TLS 上的0-RTT 时不会发生这种情况,这恰恰是因为 TCP 握手需要在0-RTT 请求连同 TLS 握手一起发送之前首先完成。

因此,QUIC 在响应0-RTT 请求时必须保守,在客户端被验证为真正的客户端而不是受害者之前,限制它响应发送的数据量。对于 QUIC,这个数据量被设置为从客户端接收数据量的三倍。

换句话说,QUIC 的最大“增益”为3,这被认为是性能有用性和安全风险之间可以接受的权衡(特别是与一些增益超过51000倍的事件相比)。因为客户机通常首先发送一到两个数据包,所以 QUIC 服务器的0-RTT 应答的上限将仅为4到6 KB (包括其他 QUIC 和 TLS 开销!)这可不怎么令人印象深刻。

此外,其他安全问题可能导致,例如,“重播攻击”,这限制了您可以执行的 HTTP 请求的类型。例如,Cloudflare 只允许0-RTT 中没有查询参数的 HTTPGET 请求。这进一步限制了0-RTT 的有用性。

幸运的是,QUIC 有更好的选择。例如,服务器可以检查0-RTT 是否来自它以前有过有效连接的 IP。但是,这只有在客户机保持在同一个网络上时才有效(这在一定程度上限制了 QUIC 的连接迁移特性)。而且即使它工作,QUIC 的响应仍然受到我们上面讨论的拥塞控制器的慢启动逻辑的限制; 因此,除了节省一次往返行程之外,没有额外的大规模速度提升。

你知道吗?
值得注意的是,QUIC 的三倍放大限制也计入了图2c 中正常的非0-RTT 握手过程。这可能是一个问题,例如,如果服务器的 TLS 证书太大,无法放入4至6KB 内。在这种情况下,它必须被分割,第二个数据块必须等待第二个往返行程被发送(在收到前几个数据包的确认之后,表明客户机的 IP 没有被欺骗)。在这种情况下,QUIC 的握手可能仍然需要两次往返等于 TCP + TLS! 这就是为什么对于 QUIC,技术如证书压缩会格外重要

你知道吗?
可能某些高级设置能够减轻这些问题,从而使0-RTT 更加有用。例如,服务器可以记住最后一次看到一个客户端时它有多少可用带宽,这样就不会受到拥塞控制重新连接(非欺骗)客户端的缓慢启动的限制。这是在学术界的研究, 甚至还有一个拟议延期 ,一些公司已经在做这类事情来提高 TCP 的速度
另一个选择是拥有客户发送一个或两个以上的数据包。例如,使用填充发送7个以上的数据包) ,因此即使在连接迁移之后,三倍的限制也会转化为更有趣的12到14 KB 的响应。我写过这个在我的一篇论文里.
最后,(行为不当的) QUIC 服务器也可以故意增加三倍的限制,如果他们觉得这样做是安全的,或者如果他们不关心潜在的安全问题(毕竟protocol police没有防止这种情况)

这一切意味着什么?

QUIC 用0-RTT 实现的更快的连接设置实际上更像是一个微观优化,而不是一个革命性的新特性。与最先进的 TCP + TLS 1.3设置相比,它最多可以节省一次往返。在第一个往返过程中实际可以发送的数据量还受到一些安全考虑的限制。

因此,如果您的用户所在的网络延迟非常高(比如说,超过200毫秒的实时传输时间的卫星网络) ,或者您通常不发送太多数据,那么这个特性将非常有用。后者的一些例子是高度缓存的网站,以及定期通过 API 和其他协议(如 DNS-over-QUIC)获取小更新的单页应用程序。Google 看到 QUIC 非常好的0-RTT 结果的原因之一是,它在已经进行了大量优化的搜索页面上进行了测试,那里的查询响应非常小。

在其他情况下,您最多只能获得几十毫秒的时间,如果您已经在使用 CDN (如果您关心性能,就应该这样做!) ,那么获得的时间就更少了.

连接迁移

第三个性能特性通过保持现有连接的完整性,使 QUIC 在网络之间传输时更快。虽然这确实有效,但是这种类型的网络更改并不经常发生,而且连接仍然需要重置它们的发送速率。

如第1部分所述,QUIC 的连接 ID (CID)允许它在交换网络时执行连接迁移。我们通过一个客户端从 Wi-Fi 网络迁移到4G,同时进行大文件下载来说明这一点。在 TCP 上,该下载可能必须中止,而对于 QUIC,它可能会继续。

不过,首先要考虑这种情况实际发生的频率。你可能认为这种情况也发生在建筑物内部的 Wi-Fi 接入点之间,或者在路上移动时在移动信号塔之间。然而,在这些设置中(如果设置正确的话) ,您的设备通常会保持其 IP 完好无损,因为无线基站之间的转换是在较低的协议层完成的。因此,只有当你在完全不同的网络之间移动时才会发生这种情况,我得说这种情况并不常见。

其次,我们可以询问除了大文件下载和实时视频会议和流之外,这是否也适用于其他用例。如果你在交换网络的确切时刻加载网页,你可能不得不重新请求一些(稍后的)资源。

但是,加载页面通常需要几秒钟的时间,因此与网络交换机重合也不是很常见。此外,对于这是一个紧迫问题的用例,其他缓解措施通常已经到位。例如,提供大文件下载的服务器可以支持 HTTP 范围请求,以允许可恢复的下载。

因为在网络1下载和网络2可用之间通常有一些重叠时间,视频应用程序可以打开多个连接(每个网络1个) ,在旧网络完全消失之前同步它们。用户仍然会注意到这个开关,但它不会完全删除视频提要。

第三,不能保证新网络的可用带宽与旧网络一样多。因此,即使概念连接保持不变,QUIC 服务器也不能保持高速发送数据。相反,为了避免新网络过载,它需要重置(或至少降低)发送速率,并在拥塞控制器的慢启动阶段重新启动。

因为这个初始发送速率通常太低,无法真正支持视频流等内容,所以即使在 QUIC 上,您也会看到一些质量损失或问题。在某种程度上,连接迁移与其说是为了提高性能,不如说是为了防止服务器上的连接上下文混乱和开销。

你知道吗?
注意,正如上面讨论的0-RTT,我们可以设计一些改进连接迁移的高级技术。例如,我们可以再次尝试记住有多少带宽可用,上一次在给定的网络上,并尝试更快地升级到新的迁移级别。此外,我们可以设想不仅仅是在网络之间切换,而是同时使用两者。这个概念叫做多路径。我们将在下面更详细地讨论它.

到目前为止,我们主要讨论了主动连接迁移,即用户在不同网络之间移动。然而,也存在被动连接迁移的情况,即某个网络本身改变了参数。网络地址转换(NAT)重新绑定就是一个很好的例子。虽然对 NAT 的全面讨论超出了本文的范围,但它主要意味着连接的端口号可以在任何给定的时间更改,而无需警告。在大多数路由器中,UDP 比 TCP 更经常出现这种情况。

如果发生这种情况,QUIC CID 将不会改变,并且大多数实现将假设用户仍然在同一物理网络上,因此不会重置拥塞窗口或其他参数。QUIC 还包括一些特性,如 PING 和超时指示器,以防止这种情况发生,因为这种情况通常发生在长空闲连接中。

我们在第1部分中讨论过,出于安全原因,QUIC 不仅仅使用单个 CID。相反,它在执行主动迁移时更改 CID。实际上,这甚至更复杂,因为客户机和服务器都有单独的 CID 列表(在 QUIC RFC 中称为源 CID 和目标 CID)。下面的图5说明了这一点。

这样做是为了允许每个端点选择自己的 CID 格式和内容,这反过来又是允许高级路由和负载平衡逻辑的关键。有了连接迁移,负载均衡器就不能再仅仅查看4元组来标识连接并将其发送到正确的后端服务器。但是,如果所有 QUIC 连接都使用随机 CID,那么负载平衡器的内存需求将大大增加,因为它需要存储 CID 到后端服务器的映射。此外,这对连接迁移仍然不起作用,因为 CID 会更改为新的随机值。

因此,部署在负载均衡器后面的 QUIC 后端服务器必须具有可预测的 CID 格式,这样负载均衡器即使在迁移之后也可以从 CID 派生正确的后端服务器。IETF 的提议文档中描述了这样做的一些选项。为了使这一切成为可能,服务器需要能够选择自己的 CID,如果连接发起者(对于 QUIC 来说,始终是客户机)选择了 CID,这是不可能的。这就是为什么在 QUIC 中客户机和服务器 CID 之间存在分离的原因。

这一切意味着什么?

因此,连接迁移是一个情景特性。例如,Google 的初步测试显示,其用例的改进百分比很低。许多 QUIC 实现还没有实现这个特性。即使是那些做到这一点的公司,通常也会将其局限于移动客户端和应用程序,而不是桌面应用程序。有些人甚至认为不需要这个特性,因为在大多数情况下,用0-RTT 打开一个新连接应该具有类似的性能属性。

不过,根据您的用例或用户配置文件,它可能会产生很大的影响。如果你的网站或应用程序在移动过程中使用频率最高(比如 Uber 或谷歌地图) ,那么你可能会比你的用户通常坐在办公桌后面受益更多。同样,如果你专注于持续的互动(视频聊天,协同编辑,或者游戏) ,那么你最坏的情况应该比你有一个新闻网站更好。

队头阻塞清除

第四个性能特性旨在通过减轻线头(HoL)阻塞问题,使 QUIC 在具有高丢包量的网络上运行更快。虽然这在理论上是正确的,但我们将看到,在实践中,这可能只会为网页加载性能提供很小的好处。

不过,要理解这一点,我们首先需要绕一个弯,讨论流优先级和多路复用。

流程优先排序

正如第1部分所讨论的,单个 TCP 包丢失可能会延迟多个传输中资源的数据,因为 TCP 的字节流抽象将所有数据都视为单个文件的一部分。另一方面,QUIC 非常清楚存在多个并发的字节流,并且可以在每个流的基础上处理丢失。然而,正如我们已经看到的,这些流并不是真正的并行传输数据: 相反,流数据是多路复用到单个连接上的。这种多路复用可以以许多不同的方式发生。

例如,对于流 a、 b 和 c,我们可能会看到 ABCABCABCABCABCABCABCABC 的数据包序列,在这个序列中,我们改变每个数据包中的活动流(我们称之为循环)。然而,我们也可能看到 AAAAAAAABBBBBBBBCCCCCCCC 的相反模式,每个流在开始下一个流之前完全完成(让我们称之为顺序)。当然,在这些极端之间还有许多其他的选择(AAABBCAAAABBC… 、 AABBCCAABBCC… 、 ABABABCCCC… 等等)。多路复用方案是动态的,由 HTTP 级别的流优先级特性驱动(本文稍后讨论)。

事实证明,您选择的多路复用方案可以对网站加载性能产生巨大的影响。您可以在下面的视频中看到这一点,由 Cloudflare 提供,因为每个浏览器都使用不同的多路复用器。原因是相当复杂的,我已经写了几篇关于这个主题的学术论文,以及在一次会议上谈论它。Webpagetest 名人帕特里克•米南(patrickmeenan)甚至就这个话题制作了一个长达3小时的教程。

幸运的是,我们可以相对容易地解释基础知识。正如您可能知道的,一些资源可以呈现阻塞。对于 CSS 文件和 HTML head 元素中的一些 JavaScript,就是这种情况。在加载这些文件时,浏览器无法绘制页面(或者,例如,执行新的 JavaScript)。

此外,CSS 和 JavaScript 文件需要完整下载才能使用(尽管它们通常可以增量解析和编译)。因此,这些资源需要以最高的优先级尽快加载。让我们考虑一下,如果 A、 B 和 C 都是呈现阻塞资源,会发生什么情况。

如果我们使用循环多路复用器(图6中的上一行) ,我们实际上会延迟每个资源的总完成时间,因为它们都需要与其他资源共享带宽。由于我们只能在它们完全装载后才能使用它们,这会造成很大的延迟。然而,如果我们按顺序复用它们(图6中的底部行) ,我们将看到 A 和 B 完成得更早(并且可以被浏览器使用) ,而不会实际延迟 C 的完成时间。

但是,这并不意味着顺序多路复用总是最好的,因为一些(大部分是非呈现阻塞的)资源(如 HTML 和渐进式 JPEG)实际上可以增量处理和使用。在这些情况下(以及其他一些情况下) ,使用第一个选项(或者至少是介于两者之间的选项)是有意义的。

尽管如此,对于大多数网页资源来说,事实证明顺序多路复用性能最好。例如,上面视频中的谷歌浏览器就是这么做的,而 Internet Explorer 使用的是最坏情况下的循环多路复用器。

分组丢失弹性

既然我们知道所有流并不总是在同一时间处于活动状态,而且它们可以以不同的方式进行复用,那么我们就可以考虑如果丢包会发生什么情况。如第1部分所述,如果一个 QUIC 流经历数据包丢失,那么仍然可以使用其他活动流(而在 TCP 中,所有活动流都将暂停)。

然而,正如我们刚才所看到的,拥有许多并发的活动流对于 web 性能来说通常并不是最佳的,因为它会延迟一些关键的(呈现阻塞)资源,即使没有包丢失!我们宁愿只有一个或两个活动在同一时间,使用顺序多路复用器。然而,这减少了 QUIC 的 HoL 阻塞去除的影响。

例如,假设发送方可以在给定的时间传输12个数据包(参见下面的图7)ーー请记住,这是受拥塞控制器的限制的。如果我们用流 A 的数据填充所有这12个数据包(因为它具有高优先级和呈现阻塞ーー想想 main.js) ,那么在这12个数据包窗口中只有一个活动流。

例如,假设发送方可以在给定的时间传输12个数据包(参见下面的图7)ーー请记住,这是受拥塞控制器的限制的。如果我们用流 A 的数据填充所有这12个数据包(因为它具有高优先级和呈现阻塞ーー想想 main.js) ,那么在这12个数据包窗口中只有一个活动流。

如果其中一个数据包丢失了,那么 QUIC 仍然会完全被 HoL 阻塞,因为除了 A 之外,它根本没有其他流可以处理: 所有的数据都是 A 的,所以所有的数据都必须等待(我们没有 B 或 C 数据要处理) ,类似于 TCP。

我们看到我们有一种矛盾: 顺序多路复用(AAAABBBBCCCC)通常对 Web 性能更好,但它不允许我们利用 QUIC 的 HoL 阻塞消除很多优势。循环多路复用(ABCABCABCABC)可以更好地对抗 HoL 阻塞,但对网络性能的影响更大。因此,一个最佳实践或优化最终可能会毁掉另一个最佳实践或优化。

还有更糟的。到目前为止,我们一直假设每个数据包一次丢失一个。然而,这并不总是正确的,因为在互联网上的数据包丢失往往是“突发性的”,这意味着多个数据包经常在同一时间丢失。

正如上面所讨论的,数据包丢失的一个重要原因是网络负载过多,不得不丢弃多余的数据包。这就是为什么拥塞控制器开始发送缓慢。然而,它继续增长其发送速率,直到… 有数据包丢失!

换句话说,旨在防止网络过载的机制实际上使网络过载(尽管是以受控的方式)。在大多数网络中,这发生在相当长的一段时间之后,当发送速率增加到每次往返数百个数据包时。当它们达到网络的极限时,它们中的几个通常一起掉落,导致突发性损失模式。

你知道吗?
这就是为什么我们希望对 HTTP/2使用单个(TCP)连接,而不是对 HTTP/1.1使用6到30个连接的原因之一。因为每个单独的连接以几乎相同的方式提高其发送速率,HTTP/1.1在开始时可以获得很好的加速,但是连接实际上可能开始导致大量数据包丢失。因为它们导致网络超载
当时,Chromium developers 猜测这种行为造成了大部分在互联网上看到的数据包丢失。这也是为什么 BBR 已经成为一个经常使用的拥塞控制算法的原因之一,因为它使用观察到的 RTT 波动,而不是分组丢失,来评估可用的带宽

你知道吗?
数据包丢失的其他原因可能导致丢失(或不能使用)的数据包更少或个别,特别是在无线网络中。然而,这些损失通常在较低的协议层检测到,并在两个本地实体(比如智能手机和4G 蜂窝塔)之间解决,而不是通过客户端和服务器之间的重传。这些通常不会导致真正的端到端数据包丢失,而是表现为数据包延迟的变化(或“抖动”)和重新排序的数据包到达

因此,假设我们使用一个每包循环多路复用器(ABCABCABCABCABCABCABC…)来最大限度地去除 HoL 阻塞,而我们只得到4个包的突然丢失。我们看到,这将始终影响所有3个流(见图8,中间行) !在这种情况下,QUIC 的 HoL 阻塞删除没有提供任何好处,因为所有流都必须等待它们自己的重新传输。

为了降低多个流受到有损突发影响的风险,我们需要为每个流连接更多的数据。例如,AABBCCAABBCCAABBCCAABBBCC… 是一个小的改进,而 AAAABBBBCCAAABBBBCCCC… (见上面图8的底部行)甚至更好。您可以再次看到,更顺序的方法更好,即使这样可以减少多个并发活动流的可能性。

最后,预测 QUIC 的 HoL 阻塞消除的实际影响是困难的,因为它取决于流的数量,损失突发的大小和频率,流数据的实际使用情况等。然而,目前的大多数结果表明,它对网页加载的用例没有多大帮助,因为在那里我们通常需要更少的并发流。

如果您想要更多关于这个主题的细节或者只是一些具体的例子,请查看我的关于 HTTP HoL 阻塞的深入文章。

你知道吗?
前面的章节一样,一些先进的技术可以在这里帮助我们。例如,现代拥塞控制器使用packet pacing 。这意味着他们不发送,例如,100包在一个突发,而是把它们分开,这在概念上降低了网络超载的几率,并且QUIC 恢复 RFC 强烈建议使用它.。互补的,一些拥塞控制算法,如BRR 不要一直增加它们的发送速率,直到它们导致包丢失,而是在此之前退出(例如,通过观察 RTT 波动,因为当网络变得过载时 RTT 也会上升)
虽然这些方法降低了丢包的总体机会,但并不一定降低其突发性

这一切意味着什么?

理论上,QUIC 的 HoL 阻塞移除意味着它(和 HTTP/3)应该在有损网络上表现得更好,但实际上这取决于很多因素。因为网页加载的用例通常倾向于更顺序的多路复用设置,并且因为数据包丢失是不可预测的,所以这个特性可能主要影响最慢的1% 的用户。然而,这仍然是一个非常活跃的研究领域,只有时间会告诉我们答案。

尽管如此,还是有一些情况可以看到更多的改善。这些大多不在第一个完整页面加载的典型用例之内ーー例如,当资源没有呈现阻塞时,当它们可以增量处理时,当流完全独立时,或者当同时发送的数据较少时。

这方面的例子包括对缓存良好的页面的重复访问、后台下载以及单页应用程序中的 API 调用。例如,Facebook 在使用 HTTP/3加载本地应用程序中的数据时,看到了 HoL 阻塞移除带来的一些好处。

UDP 和 TLS 性能

QUIC 和 HTTP/3的第五个性能方面是关于它们在网络上实际创建和发送数据包的效率和性能。我们将看到 QUIC 使用 UDP 和重加密可以使它比 TCP 慢一些(但情况正在改善)。

首先,我们已经讨论过 QUIC 对 UDP 的使用更多的是关于灵活性和可部署性,而不是性能。直到最近,通过 UDP 发送 QUIC 数据包通常比发送 TCP 数据包慢得多,这一事实进一步证明了这一点。这部分是因为这些协议通常在哪里以及如何实现(参见下面的图9)。

如上所述,TCP 和 UDP 通常直接在操作系统的快速内核中实现。相比之下,TLS 和 QUIC 实现大多在较慢的用户空间中(注意,QUIC 并不真正需要这样做ーー这样做主要是因为它更加灵活)。这使得 QUIC 已经比 TCP 慢了一点。

此外,当从我们的用户空间软件(比如浏览器和 Web 服务器)发送数据时,我们需要将这些数据传递给操作系统内核,然后操作系统内核使用 TCP 或 UDP 实际将数据放到网络上。传递这些数据是使用内核 API (系统调用)完成的,这涉及到每个 API 调用一定数量的开销。对于 TCP,这些开销比 UDP 低得多。

这主要是因为,从历史上看,TCP 的使用要比 UDP 多得多。因此,随着时间的推移,TCP 实现和内核 API 增加了许多优化,以将数据包的发送和接收开销减少到最低限度。许多网络接口控制器(NIC)甚至具有内置的 TCP 硬件卸载特性。然而,UDP 就没有那么幸运了,因为它更有限的使用并不能证明在附加优化方面的投资是合理的。在过去的五年中,这种情况幸运地改变了,大多数操作系统也增加了 UDP 的优化选项。

其次,QUIC 有很多开销,因为它分别加密每个数据包。这比在 TCP 上使用 TLS 要慢,因为在 TCP 上可以对数据包进行块加密(一次最多可以加密16KB 或11个数据包) ,这样效率更高。这是在 QUIC 中做出的一个有意识的权衡,因为批量加密可能导致其自身形式的 HoL 阻塞。

与第一点不同,我们可以添加额外的 API 来使 UDP (因此是 QUIC)更快,在这里,QUIC 总是有一个与 TCP + TLS 相比固有的缺点。然而,这在实践中也是非常容易管理的,例如,优化的加密库和允许对 QUIC 数据包头进行批量加密的聪明方法。

因此,尽管 Google 最早的 QUIC 版本仍然比 TCP + TLS 慢一倍,但是从那以后情况确实有所改善。例如,在最近的测试中,微软经过大量优化的 QUIC 栈能够获得7.85 Gbps 的速度,相比之下,在同一个系统上,TCP + TLS 的速度是11.85 Gbps (因此在这里,QUIC 的速度大约是 TCP + TLS 的66%)。

这与最近的 Windows 更新有关,它使 UDP 更快(完全比较而言,该系统的 UDP 吞吐量为19.5 Gbps)。Google 的 QUIC 栈的最优化版本目前比 TCP + TLS 慢20% 左右。Ffast 在一个不那么先进的系统上进行的早期测试,使用了一些技巧,甚至声称性能相当(大约450Mbps) ,这表明根据用例的不同,QUIC 肯定可以与 TCP 竞争。

然而,即使 QUIC 的速度是 TCP + TLS 的两倍,它也没有那么糟糕。首先,QUIC 和 TCP + TLS 处理通常不是服务器上发生的最繁重的事情,因为其他逻辑(比如 HTTP、缓存、代理等)也需要执行。因此,实际上运行 QUIC 并不需要两倍的服务器(不清楚它在真正的数据中心中会产生多大的影响,因为没有一家大公司发布过这方面的数据)。

其次,在未来仍然有很多优化 QUIC 实现的机会。例如,随着时间的推移,一些 QUIC 实现将(部分地)迁移到操作系统内核(很像 TCP)或绕过它(一些已经这样做了,比如 MsQuic 和 Quant)。我们还可以预期 QUIC 特定的硬件将变得可用。

尽管如此,仍然可能会有一些 TCP + TLS 仍然是首选的用例。例如,Netflix 已经表示它可能不会很快转向 QUIC,因为它已经大量投资于通过 TCP + TLS 传输视频的自定义 FreeBSD 设置。

同样,Facebook 表示,QUIC 可能主要用于终端用户和 CDN 边缘之间,但不会用于数据中心之间或边缘节点和原始服务器之间,因为它的开销较大。一般来说,非常高的带宽场景可能会继续支持 TCP + TLS,特别是在未来几年。

你知道吗?
优化网络堆栈是一个深奥而技术性的兔子洞,上面的内容仅仅触及表面(并且忽略了许多细微差别)。如果你足够勇敢或者你想知道GRO/GSO, SO_TXTIME, kernel bypass, sendmmsg() 还有recvmmsg() 的含义。我可以推荐一些优化 QUIC 的优秀文章
Cloudflare
Fastly
code walkthrough by Microsoft Microsoft
an in-depth talk from Cisco
Finally, a Google engineer gave a very interesting keynote about 。optimizing their QUIC implementation over time

这一切意味着什么?

QUIC 对 UDP 和 TLS 协议的特殊使用历来使它比 TCP + TLS 慢得多。然而,随着时间的推移,已经做出了一些改进(并将继续实施) ,在一定程度上缩小了差距。不过,在典型的网页加载用例中,您可能不会注意到这些差异,但是如果维护大型服务器群,这些差异可能会让您头疼。

HTTP/3特性

到目前为止,我们主要讨论了 QUIC 与 TCP 之间的新性能特性。然而,HTTP/3和 HTTP/2的区别是什么?正如第1部分所讨论的,HTTP/3实际上是 HTTP/2-over-QUIC,因此,新版本中没有引入真正的大型新特性。这不同于从 HTTP/1.1迁移到 HTTP/2,后者规模更大,并引入了新特性,如头压缩、流优先级排序和服务器推送。这些特性仍然存在于 HTTP/3中,但是它们在底层的实现方式上有一些重要的不同。

这主要是因为 QUIC 移除 HoL 阻塞的工作原理。正如我们已经讨论过的,流 B 上的丢失不再意味着流 A 和 C 必须等待 B 的重新传输,就像它们在 TCP 上所做的那样。因此,如果 A、 B 和 C 各自按照这个顺序发送一个 QUIC 数据包,那么它们的数据很可能以 A、 C、 B 的形式传递到(并由)浏览器处理!换句话说,与 TCP 不同,QUIC 不再是跨不同流的完全排序!

这对 HTTP/2来说是个问题,因为它在设计许多特性时确实依赖于 TCP 的严格排序,这些特性使用特殊的控制消息和数据块。在 QUIC 中,这些控制消息可能以任何顺序到达(并应用) ,甚至可能使特性做与预期相反的事情!对于本文来说,技术细节同样是不必要的,但是本文的前半部分应该让您了解这种复杂性有多么愚蠢。

因此,这些特性的内部机制和实现必须针对 HTTP/3进行更改。一个具体的例子是 HTTP 头压缩,它降低了重复的大型 HTTP 头(例如 cookie 和用户代理字符串)的开销。在 HTTP/2中,这是使用 HPACK 设置完成的,而对于 HTTP/3,这已经被重新设置为更复杂的 QPACK。这两个系统提供相同的特性(即头压缩) ,但是方式完全不同。在 Litespeedblog 上可以找到关于这个主题的一些出色的深入技术讨论和图表。

对于驱动流多路复用逻辑的优先级特性也是类似的,我们在上面已经简要讨论过了。在 HTTP/2中,这是通过一个复杂的“依赖树”设置来实现的,该设置显式地尝试对所有页面资源及其相互关系建模(更多信息见“ HTTP 资源优先级的终极指南”)。在 QUIC 上直接使用这个系统将导致一些潜在的非常错误的树布局,因为将每个资源添加到树中将是一个单独的控制消息。

此外,这种方法被证明是不必要的复杂,导致许多服务器上的许多实现错误和效率低下 以及 性能低下 。这两个问题都导致了为 HTTP/3以一种更简单的方式重新设计了优先级系统。这种更简单的设置使得一些高级场景难以或不可能实施(例如,在单个连接上代理来自多个客户端的流量) ,但仍然支持广泛的网页加载优化选项。

虽然这两种方法提供了相同的基本特性(指导流多路复用) ,但希望 HTTP/3更简单的设置将减少实现错误。

最后,还有服务器推送。这个特性允许服务器发送 HTTP 响应,而无需首先等待对它们的显式请求。理论上,这可以带来极好的性能提升。然而,在实践中,它被证明是很难正确使用和不一致的实现。因此,它甚至可能会被从谷歌 Chrome 中删除。

尽管如此,它仍然被定义为 HTTP/3中的一个特性(尽管很少有实现支持它)。虽然它的内部工作方式没有像前两个特性那样发生很大变化,但是它也适应了 QUIC 的非确定性排序。不过,遗憾的是,这对解决一些长期存在的问题几乎没有什么帮助。

这一切意味着什么?

如前所述,HTTP/3的大部分潜力来自底层的 QUIC,而不是 HTTP/3本身。虽然该协议的内部实现与 HTTP/2非常不同,但其高级性能特性以及如何使用它们仍然保持不变。

未来需要注意的发展

在本系列文章中,我经常强调,更快的进化和更高的灵活性是 QUIC 的核心方面(进一步说,也是 HTTP/3)。因此,人们已经在开发协议的新扩展和应用程序就不足为奇了。下面列出的是你可能会遇到的主要问题:

  • 前向错误更正.这项技术的目的是,再一次提高 QUIC 对数据包丢失的恢复能力…它通过发送冗余的数据副本来实现这一点(尽管经过巧妙的编码和压缩,数据不会那么大)。然后,如果数据包丢失但冗余数据到达,则不再需要重传。这最初是 Google QUIC 的一部分(这也是为什么人们说 QUIC 对于数据包丢失很有效的原因之一) ,但是它没有包含在标准的 QUIC 版本1中,因为它的性能影响还没有得到证实。尽管如此,研究人员现在正在用它进行积极的实验,你可以通过使用这个下载应用程序 看实验
  • 多径 QUIC.我们之前已经讨论过连接迁移,以及从 Wi-Fi 迁移到蜂窝网络时如何提供帮助。然而,这难道不意味着我们可以同时使用 Wi-Fi 和手机吗。同时使用这两个网络将给我们更多的可用带宽和增强的健壮性!这是多路径背后的主要概念。这也是 Google 尝试过的东西,但是由于其固有的复杂性,它没有进入 QUIC 版本1。然而,研究人员有展示过它的高潜力,它可能使它成为 QUIC 版本2。注意TCP 多路径也存在,但是用了将近十年的时间才变得实际可用
  • QUIC 和 HTTP/3上的不可靠数据。正如我们所看到的,QUIC 是一个完全可靠的协议。但是,由于它运行在不可靠的 UDP 上,因此我们可以向 QUIC 添加一个特性来发送不可靠的数据。这在建议的数据报扩展中有所概述。当然,你可能不想用它来发送网页资源,但是它对于游戏和实时视频流之类的东西可能很方便。通过这种方式,用户可以享受到 UDP 的所有好处,但需要使用 QUIC 级别的加密和(可选的)拥塞控制
  • 网上传输。浏览器不会直接向 JavaScript 公开 TCP 或 UDP,这主要是出于安全考虑。相反,我们必须依赖 HTTP 级别的 API,比如 Fetch 和更加灵活的 API。 比如WebSocket 还有WebRTC协议。这一系列选项中最新的一个称为 WebTransport,它主要允许您以更低级的方式使用 HTTP/3(扩展为 QUIC)(尽管如果需要,它也可以回到 TCP 和 HTTP/2)。至关重要的是,它将包括通过 HTTP/3使用不可靠数据的能力(参见前面的观点) ,这将使诸如游戏之类的事情更容易在浏览器中实现。当然,对于普通(JSON) API 调用,您仍将使用 Fetch,如果可能的话,它还将自动使用 HTTP/3。WebTransport 目前仍处于激烈的讨论之中,因此目前还不清楚它最终会是什么样子。在所有浏览器中,目前只有 Chromium 在公共浏览器上运行 概念验证实现
  • DASH 和 HLS 视频流。对于非实时视频(想想 YouTube 和 Netflix) ,浏览器通常使用动态自适应 HTTP 流(dASH)或 HTTP Live Streaming (HLS)协议。这两种方法基本上都意味着将视频编码成更小的块(2到10秒)和不同的质量等级(720p、1080p、4K 等)。在运行时,浏览器估计您的网络能够处理的最高质量(或者对于给定的用例来说是最优的) ,并且它通过 HTTP 从服务器请求相关文件。因为浏览器不能直接访问 TCP 协议栈(这通常在内核中实现) ,所以它偶尔会在这些估算中出现一些错误,或者需要一段时间来对不断变化的网络条件做出反应(导致视频停止)。因为 QUIC 是作为浏览器的一部分实现的,所以可以通过 使流估计器能够访问低级协议信息 (例如损耗率、带宽估计等) 为视频流混合可靠和不可靠的数据 还有一些有希望的结果
  • HTTP/3以外的协议。于 QUIC 是一个通用的传输协议,我们可以期望许多现在运行在 TCP 上的应用层协议也能在 QUIC 上运行。一些正在进行的工作包括DNS-over-QUIC ,SMB-over-QUIC,甚至SSH-over-QUIC. 因为这些协议通常具有与 HTTP 和网页加载非常不同的需求,所以我们讨论的 QUIC 的性能改进可能对这些协议有更好的效果

这一切意味着什么?

QUIC 版本1仅仅是个开始。谷歌早期试验过的许多高级性能导向特性并没有进入第一次迭代。然而,目标是快速发展协议,以高频率引入新的扩展和特性。因此,随着时间的推移,QUIC (和 HTTP/3)应该明显比 TCP (和 HTTP/2)更快、更灵活。

结论

在本系列的第二部分中,我们讨论了 HTTP/3,特别是 QUIC 的许多不同的性能特征和方面。我们已经看到,虽然这些特性中的大多数看起来非常有影响力,但是在实践中,在我们一直在考虑的 Web 页面加载用例中,它们可能不会对普通用户产生太大影响。

例如,我们已经看到 QUIC 使用 UDP 并不意味着它可以突然比 TCP 使用更多的带宽,也不意味着它可以更快地下载您的资源。经常被称赞的0-RTT 特性实际上是一个微型优化,它可以节省您一次往返的时间,您可以发送大约5 KB (在最坏的情况下)。

HoL 阻塞移除不能很好地工作,如果有突发包丢失或当您加载呈现阻塞资源。连接迁移是高度情景化的,HTTP/3没有任何可以使其比 HTTP/2更快的主要新特性。

因此,您可能希望我建议您跳过 HTTP/3和 QUIC。何必呢,对吧?但是,我绝对不会做这样的事情!尽管这些新协议可能不会对快速(城市)网络上的用户有太大帮助,但是这些新特性确实有可能对高度移动的用户和慢速网络上的人产生巨大的影响。

即使在西方市场,如我自己的比利时,我们通常有快速设备和接入高速蜂窝网络,这些情况可能会影响1% 到甚至10% 的用户基础,取决于你的产品。一个例子是,有人在火车上拼命地想在你的网站上查找一条重要的信息,但却不得不等待45秒才能载入。我当然知道我已经处在那种情况下,希望有人已经部署 QUIC 让我摆脱它。

然而,还有一些国家和地区的情况更加糟糕。在那里,普通用户看起来更像是比利时最慢的10% ,最慢的1% 可能根本看不到加载页面。在世界许多地方,网络性能是一个易访问性和包容性的问题。

这就是为什么我们永远不应该仅仅在我们自己的硬件上测试我们的页面(但是也应该使用 Webpagetest 这样的服务) ,这也是为什么我们一定要部署 QUIC 和 HTTP/3的原因。特别是如果你的用户经常在移动或不太可能访问快速蜂窝网络,这些新的协议可能会带来很大的不同,即使你没有注意到你的有线 MacBook Pro。要了解更多细节,我强烈推荐法斯特关于这个问题的文章。

如果这还不能完全说服您,那么请考虑 QUIC 和 HTTP/3将继续发展,并在未来几年中变得更快。在协议方面获得一些早期经验将在今后获得回报,使您能够尽快获得新特性的好处。此外,QUIC 在后台加强了安全性和隐私最佳实践,这对所有用户都有好处。

终于被说服了?然后继续阅读本系列的第3部分,了解如何在实践中使用新协议。

  • 第1部分: HTTP/3历史记录和核心概念:本文针对 HTTP/3和一般协议的新手,主要讨论基础知识
  • 第2部分: HTTP/3性能特性 :这一个更深入和技术性。人们谁已经知道的基本知识可以从这里开始
  • 第3部分: 实用 HTTP/3部署选项:本系列的第三篇文章解释了自己部署和测试 HTTP/3所涉及的挑战。它详细说明了如何以及是否应该更改您的网页和资源

HTTP/3: 性能改进(第2部分)相关推荐

  1. .NET 3.5 中WCF客户端代理性能改进以及最佳实践

    介绍 在.NET 3.0 SP1(与.NET 3.5一起发布) 中,WCF客户端创建有一个重要的性能改进.对BasicHttpBinding 来说,性能已经接近于创建ASMX代理. ASMX 代理 v ...

  2. PowerShell Core 6.2 发布,侧重于性能改进

    百度智能云 云生态狂欢季 热门云产品1折起>>>   PowerShell Core 6.2 GA 已发布,PowerShell Core 是 PowerShell 的开源版本,适用 ...

  3. Windows 7 SP1确实将有性能改进

    虽然微软一再刻意淡化Windows 7 SP1的重要性,但这都阻挡不了我们对新系统第一个服务包的期待,而最新消息显示它确实也会带来一定程度的性能改进.微软此前曾表示,Windows 7 SP1只是一次 ...

  4. Qt 5.12 LTS(长期维护版本)中Qt Quick的性能改进

    我们一直致力于提高Qt的性能和优化其内存消耗.Qt 5.12的一个重点关注是在于减少QML引擎的内存消耗和优化JavaScript性能. 与上一个长期支持版Qt 5.6 LTS相比,Qt 5.9 LT ...

  5. Entity Framework Core 6.0 预览4 性能改进

    起因 微软在Build2021开发者大会上,发布Entity Framework Core 6.0(简称EFCore 6)预览第四版,号称是性能版本,性能提升主要对于Entity Framework  ...

  6. .NET 5 中的正则引擎性能改进(翻译)

    前言 System.Text.RegularExpressions 命名空间已经在 .NET 中使用了多年,一直追溯到 .NET Framework 1.1.它在 .NET 实施本身的数百个位置中使用 ...

  7. java8hashmap_Java 8中的HashMap性能改进

    java8hashmap HashMap<K, V>是每个Java程序中快速,通用且无处不在的数据结构. 首先是一些基础知识. 您可能知道,它使用键的hashCode()和equals() ...

  8. Java 8中的HashMap性能改进

    HashMap<K, V>是每个Java程序中快速,通用且无处不在的数据结构. 首先是一些基础知识. 您可能知道,它使用键的hashCode()和equals()方法在存储桶之间拆分值. ...

  9. 【译】.NET 7 中的性能改进(十一)

    ▲ 点击上方"DotNet NB"关注公众号 回复"1"获取开发者路线图 学习分享 丨作者 / 郑 子 铭 这是DotNet NB 公众号的第215篇原创文章 ...

  10. .NET获取枚举DescriptionAttribute描述信息性能改进的多种方法

    原文:.NET获取枚举DescriptionAttribute描述信息性能改进的多种方法 一. DescriptionAttribute的普通使用方式 1.1 使用示例 DescriptionAttr ...

最新文章

  1. springboot 日志 log4j
  2. centos 下postgres源码安装
  3. Java之IO流学习总结【上】
  4. 利用Query判断checkbox是否选中的写法!(
  5. 一段典型的PHP程序都包含那些内容呢?
  6. web开发环境_Web开发人员的开发环境
  7. C++ AFX_MANAGE_STATE(AfxGetStaticModuleState())的作用
  8. RabbitMQ入门学习系列(三).消息发送接收
  9. 动态规划入门——第N个泰波那契数(Leetcode 1137)
  10. (64)Verilog HDL多模块重复例化
  11. (器) 构建自由通行的IOS开发者地图
  12. Leetcode每日一题:183.customers-who-never-order(从不订购的客户)
  13. 解决复制项目后名称不改变的问题:org.eclipse.wst.common.component
  14. 软件工程理论、方法与实践(第三章)
  15. mysql 8.0.3 rc_MySQL 8.0.3 RC 版即将发布,看看有哪些变化
  16. 神经网络matlab仿真,神经网络模型及其MATLAB仿真程序设计 周开利 等著 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...
  17. 如何查询计算机主机序列号,计算机硬盘序列号如何查询
  18. 计算机四级和网络工程师区别,计算机四级网络工程师和软考中级的网络工程师有什么区别啊?...
  19. 按键精灵注册大漠插件
  20. 2021届秋招提前批——携程数据分析笔试

热门文章

  1. 【超简单PR学习】用pr制作一个电子相册
  2. 雅思N、NG专项(目标是保证一个都不错)
  3. iphone面试笔试题目
  4. 物联网校企联盟程序设计每周练习赛(二)
  5. Linux各个发行版本代号整理
  6. 2019晋城一中开放日
  7. 草柴返利APP:淘宝天猫满减店铺优惠券领取入口怎么免费领淘宝天猫粉丝福利购大额内部隐藏优惠券?
  8. 使用fo-dicom读取Dicom文件的PixelData信息及像素信息(C# / fo-dicom)
  9. C++中的面向对象(四大基本特征与五大原则)
  10. 净水器哪个牌子好,家用净水器什么牌子好科普