性能和效率:使用 HTTP/3

已发表: 2022-03-11

HTTP/3 即将出现,紧随 HTTP/2 之后——可以说它本身还很年轻。 鉴于从 HTTP/1.1 到 HTTP/2 花了 16 年时间,真的有人关心 HTTP/3 吗?

简短的回答:是的,这很重要,你应该跟上它的速度。 这就像 HTTP/2 如何通过从 ASCII 切换到二进制来对 HTTP/1.1 做出重大改变一样。 HTTP/3 再次做出重大改变,这次是将底层传输从 TCP 切换到 UDP。

尽管 HTTP/3 仍处于设计阶段,官方规范为草稿,但它已经在部署中,您很有可能会在今天的网络上找到它的一个版本。

但是 HTTP/3 的工作方式带来了一些新的困境。 还有,有什么好处? 网络工程师、系统管理员和开发人员需要知道什么?

TL;博士

  • 更快的网站更成功。
    • HTTP/2 带来了很大的性能提升,因为它解决了HTTP 线头阻塞问题 (HOL) 。 它介绍了请求/响应多路复用、二进制帧、标头压缩、流优先级服务器推送
    • HTTP/3 甚至更快,因为它包含了所有 HTTP/2 并且还解决了TCP HOL 阻塞问题。 HTTP/3 仍然只是一个草案,但已经在部署中。 它更高效使用更少的资源(系统和网络),需要加密(SSL 证书是强制性的),并使用 UDP
  • 尽管 Web 浏览器可能会在一段时间内继续支持旧版本的 HTTP,但搜索引擎对 HTTP/3 精通网站的性能优势和优先级应该会推动新协议的采用。
  • SPDY 已过时,任何使用它的人都应该用 HTTP/2 替换它。
  • 今天的网站应该已经支持 HTTP/1.1 和 HTTP/2。
  • 在不久的将来,网站所有者可能也希望支持 HTTP/3。 然而,它比 HTTP/2 更具争议性,我们可能会看到很多大型网络只是简单地阻止它,而不是花时间处理它。

主要问题:性能和效率

网站和应用程序开发人员通常以实际使用他们的创作为目的进行构建。 有时受众群是有限的,但通常的想法只是为了获得尽可能多的用户。 自然,网站越受欢迎,它可以赚取的收入就越多。

网站加载时间延迟 100 毫秒可能会降低 7% 的转化率。

Akamai 在线零售绩效报告:毫秒至关重要(2017 年)

换句话说,一个每天销售额为 40,000 美元的电子商务网站会因为这种延迟而每年损失 100 万美元。

网站的性能对于网站变得更受欢迎绝对至关重要,这也不是什么秘密。 在线购物研究继续发现跳出率增加与加载时间延长之间的联系,以及购物体验期间购物者忠诚度与网站性能之间的联系。

研究还发现:

  • 47% 的消费者希望网页在 2 秒或更短的时间内加载。
  • 40% 的人会放弃加载时间超过 3 秒的网站。

这就是十多年前在线购物者的耐心状态。 所以性能至关重要,HTTP/2 和 HTTP/3 都意味着更好的网站性能。

HTTP/2? …那是什么?

对 HTTP/2 协议的良好理解对于理解 HTTP/3 至关重要。 首先,为什么需要 HTTP/2?

HTTP/2 最初是一个名为 SPDY 的 Google 项目,一项研究报告称,网络上最大的性能问题是延迟。 作者得出的结论是“更多的带宽并不重要(多)”:

如果我们将管道和互联网进行类比,我们可以认为互联网的带宽就像水管的直径。 较大的管道​​携带更多的水,因此您可以在两点之间输送更多的水。

同时,不管你的管子有多大,如果管子是空的,你想把水从一个点引到另一个点,水流过管子需要时间。 用互联网的话来说,水从管道的一端到另一端并再次返回所需的时间称为往返时间,或RTT

迈克·贝尔什

在这项研究中,目标是减少页面加载时间。 它表明增加带宽最初会有所帮助,因为从 1 Mbps 到 2 Mbps 会使页面加载时间减半。 然而,收益很快就趋于平稳。

页面加载时间与带宽和延迟。对于 1 Mbps 连接,加载时间从超过 3 秒开始,对于带宽为 4 Mbps 及以上的连接,加载时间在略低于 1,500 毫秒的稳定期。相比之下,加载时间几乎随延迟线性减少,从大约 3,400 毫秒(延迟 200 毫秒)到大约 1,100 毫秒(延迟 20 毫秒)。

相比之下,减少延迟有一个持续的好处,并取得了最好的结果。

HTTP HOL:行头阻塞问题

HTTP/1 协议中延迟的主要原因是行头阻塞问题。 网页(几乎总是)需要多个资源:CSS、JavaScript、字体、图像、AJAX/XMR 等。这意味着 Web 浏览器需要向服务器发出多个请求。 但是,并非所有资源都需要页面变得有用。

对于 HTTP/1.0,浏览器必须在开始下一个请求之前完全完成一个请求,包括完全接收响应。 一切都必须按顺序进行。 每个请求都会阻塞请求行,因此得名。

为了弥补 HOL 阻塞问题,Web 浏览器与单个服务器同时建立多个连接。 但他们不得不任意限制这种行为:服务器、工作站和网络可能会因连接过多而过载。

HTTP/1.1 引入了一些改进来帮助解决这个问题。 主要的一个是流水线,允许 Web 浏览器启动新请求,而无需等待先前的请求完成。 这显着改善了低延迟环境中的加载时间。

但是它仍然要求所有响应都按照它们产生的顺序依次到达,所以行首仍然被阻塞。 令人惊讶的是,许多服务器仍然没有利用此功能。

HTTP/1.1 流水线与常规 HTTP 请求的比较。常规请求具有完全串行完成的三个请求-响应往返。流水线方法总体上要快一些,因为客户端连续发送三个请求,而无需等待它们之间的响应。但是它仍然存在线头阻塞问题,因为必须按顺序发送响应。

有趣的是,HTTP/1.1 还引入了keep-alive ,它允许浏览器避免为每个 HTTP 请求创建新的 TCP 连接的开销。 这是解决 TCP 衍生的性能问题的早期尝试。 它是如此无效,以至于大多数性能专家实际上不鼓励它,因为它会因过多的非活动连接而使服务器陷入困境。 我们将在下面仔细研究 TCP,以及 HTTP/2 如何解决此问题。

HTTP/2 的 HTTP HOL 阻塞解决方案

HTTP/2 在单个连接上引入了请求-响应多路复用。 浏览器不仅可以随时启动新请求,而且可以按任何顺序接收响应——在应用程序级别完全消除了阻塞。

HTTP/2 与 SPDY 的多路复用,与上图中描述的普通和启用管道的 HTTP/1.1 相比。多路复用显示客户端的请求发送得更快,并且它的第一个请求在其第二个和第三个请求的响应之后发送了相应的响应。总体而言,总的通信时间因此显着缩短。

直接结果是,这意味着支持 HTTP/2 的 Web 服务器可以最大限度地提高效率——稍后会详细介绍。

尽管请求-响应多路复用是 HTTP/2 的主要特性,但它还包括其他几个重要特性。 读者可能会注意到它们都有些相关。

HTTP/2 二进制帧

HTTP/2 将 HTTP 协议标准从低效的人类可读 ASCII 请求-响应模型转换为高效的二进制帧。 它不再只是请求和响应:

通过 HTTP 2.0 的客户端-服务器连接。客户端同时通过流 5 发送数据,同时服务器按此顺序发送流 1 数据、流 3 标头、流 3 数据、流 1 数据等。

使用 HTTP/2,浏览器通过具有多个消息的双向流与服务器通信,每个消息由多个帧组成。

HTTP/2 HPACK(标头压缩)

HTTP/2 的新标头压缩,使用 HPACK 格式,为大多数站点节省了大量带宽。 这是因为在连接中发送的请求的大多数标头都是相同的。

HPACK 在行动。第一个请求,指定字段的值 :method、:scheme、:host、:path、accept 和 user-agent,按原样发送。第二个请求有几个字段——那些与第一个请求中的相应字段相同的字段——被剥离,因为它们的值隐含地是前一个请求的值。生成的请求要小得多,只包含 :path 的值。

Cloudflare 报告说,仅 HPACK 就可以显着节省带宽:

  • 入口标头压缩 76%
  • 总入口流量减少 53%
  • 出口标头压缩 69%
  • 总出口流量减少 1.4% 至 15%

当然,使用更少的带宽通常意味着更快的网站。

HTTP/2 流优先级和服务器推送

这就是 HTTP/2 的多路复用真正让服务器最大化效率的地方。 多路复用确实有助于在较慢的资源(例如,大图像、数据库生成的 JSON 等)之前提供更快的资源(例如,内存缓存的 JavaScript)。 但它也允许通过 HTTP/2 的流优先级来进一步提升性能。

流优先级有助于确保页面的几乎准备就绪的方面完全完成,而无需等待其他资源密集型请求完成。 这是通过加权依赖树完成的。 该树用于通知服务器应该分配最多系统资源来服务的响应。

这对于渐进式 Web 应用程序 (PWA) 尤其重要。 例如,假设一个页面有四个 JavaScript 文件。 两个用于页面功能,两个用于广告。 最坏的情况是加载一半的功能 JS 和一半的广告 JS,然后继续加载大图像,然后再加载任何剩余的 JS。 在这种情况下,页面上的任何内容最初都无法正常工作,因为一切都必须等待最慢的资源。

通过流优先级,Web 浏览器可以指示服务器在发送任何广告 JavaScript 文件之前发送两个页面功能 JS 文件。 这样用户就不必等待广告完全加载后才能使用页面的功能。 尽管整体加载时间没有改善,但感知性能已显着提高。 不幸的是,Web 浏览器中的这种行为仍然主要是算法问题,而不是 Web 开发人员指定的东西。

同样,HTTP/2 的服务器推送功能允许服务器向浏览器发送尚未发出的请求的响应! 服务器可以利用传输间隙,通过将服务器知道它将很快请求的资源预加载到浏览器中来有效地使用带宽。 这里的部分希望是消除资源内联的做法,这只会使资源膨胀并使其加载时间更长。

不幸的是,这两个功能都需要 Web 开发人员进行大量仔细配置才能真正成功。 仅仅启用它们是不够的。


HTTP/2 显然带来了许多潜在的优势——其中一些优势比其他优势更便宜。 他们在现实世界中的表现如何?

HTTP 与 HTTP/2 的采用

SPDY 创建于 2009 年。HTTP/2 于 2015 年标准化。SPDY 成为代码不稳定开发分支的名称,HTTP/2 成为最终版本。 结果就是 SPDY 已经过时了,而 HTTP/2 通常是每个人都遵循的标准。

标准化后,HTTP/2(或“h2”)的采用率迅速增长到前 1000 个网站的 40% 左右。 这主要是由代表客户部署支持的大型托管和云提供商推动的。 不幸的是,几年后,HTTP/2 的采用速度放缓,大多数互联网仍然使用 HTTP/1。

缺乏对 HTTP/2 明文模式的浏览器支持

有很多人呼吁 HTTP/2 将加密作为标准的必需部分。 相反,该标准定义了加密 (h2) 和明文 (h2c) 模式。 因此,HTTP/2 可以完全取代 HTTP/1。

尽管有标准,所有当前的网络浏览器都只支持通过加密连接的 HTTP/2,并且故意不实现明文模式。 相反,浏览器依赖 HTTP/1 向后兼容模式来访问不安全的服务器。 这是在默认情况下使网络安全的意识形态推动的直接结果。

为什么选择 HTTP/3? 它有什么不同?

随着 HTTP/2 现在解决了 HTTP 的线头阻塞问题,协议开发人员将注意力转向了下一个最大的延迟驱动因素: TCP的线头阻塞问题。

传输控制协议 (TCP)

IP(互联网协议)网络基于计算机相互发送数据包的想法。 数据包只是顶部附加一些寻址信息的数据。

但是应用程序通常需要处理数据。 为了实现这种错觉,传输控制协议 (TCP) 为应用程序提供了一个管道,数据流可以通过该管道流动。 与大多数管道一样,可以保证数据将以与输入相同的顺序退出管道,也称为“先进先出”(FIFO)。 这些特性使 TCP 非常有用并被广泛采用。

作为 TCP 提供的数据传输保证的一部分,它必须能够处理各种各样的情况。 最复杂的问题之一是如何在网络过载时提供所有数据,而不会使每个人的情况变得更糟。 用于此的算法称为拥塞控制,是互联网规范中不断发展的一部分。 如果没有足够的拥塞控制,互联网就会陷入停顿。

86 年 10 月,互联网首次出现了一系列“拥塞崩溃”。 在此期间,从 LBL 到 UC Berkeley(站点相距 400 码和三个 IMP 跃点)的数据吞吐量从 32 Kbps 下降到 40 bps。

五、雅各布森 (1988)

这就是 TCP 线头阻塞问题的来源。

TCP HOL 阻塞问题

TCP 拥塞控制通过实现数据包的退避重传机制来工作,每当检测到数据包丢失时使用。 退避旨在帮助稳定网络。 重传确保数据最终被传递。

这意味着 TCP 数据可能会乱序到达目的地,接收方有责任在将数据包重新组合到流中之前对其进行重新排序。 不幸的是,这意味着一个丢失的数据包可能会导致整个 TCP 流在服务器等待重新传输时暂停。 因此,该行的头部被阻塞。

谷歌的另一个项目旨在通过引入一种称为 QUIC 的协议来解决这个问题。

TCP HOL 通过 HTTP/2 连接阻塞。正在发送一个红色和几个绿色和蓝色的数据包,但是一个红色的数据包丢失,导致绿色和蓝色数据包的阻塞。

QUIC 协议建立在 UDP 而不是 TCP 之上,QUIC 正在形成 HTTP/3 的基础。

什么是 UDP?

用户数据报协议 (UDP) 是 TCP 的替代方案。 它不提供流的错觉或 TCP 提供的相同保证。 相反,它只是提供了一种简单的方法来将数据放入数据包中,将其寻址到另一台计算机,然后发送。 它是不可靠的、无序的,并且没有任何形式的拥塞控制。

它的目的是轻量级并提供允许通信所需的最少功能。 这样,应用程序可以实现自己的保证。 这在实时应用程序中通常非常有用。 例如,在电话通话中,用户通常更愿意立即收到 90% 的数据,而不是最终收到 100% 的数据。

HTTP/3 的 TCP HOL 解决方案

解决 TCP HOL 阻塞问题需要的不仅仅是切换到 UDP,因为仍然需要保证所有数据的传递并避免网络拥塞崩溃。 QUIC 协议旨在通过提供优化的 HTTP over UDP 类型的体验来完成所有这些工作。

由于 QUIC 接管了流管理、二进制帧等的控制权,因此在 QUIC 之上运行时,HTTP/2 所要做的事情已经不多了。 这是将 QUIC + HTTP 的新组合标准化为 HTTP/3 的部分驱动因素。

QUIC OSI 模型,以 IP 为基础,在其上构建了两个堆栈。左侧的 HTTP 协议栈在 IP 之上添加了 TCP、TLS 和 HTTP/2。右侧的 HTTP 协议栈在 IP 之上添加了 UDP、一个特殊块和“HTTP over QUIC”。特殊块包含 QUIC 和类似 TCP 的拥塞控制和丢失恢复,其中包含一个用于 QUIC 加密的单独块。

注意:QUIC 有很多版本,因为该协议已经在生产环境中开发和部署多年。 甚至还有一个名为 GQUIC 的特定于 Google 的版本。 因此,区分旧的 QUIC 协议和新的 HTTP/3 标准很重要。

始终加密

HTTP/3 包含大量从 TLS 借用但不直接使用它的加密。 HTTP/3 的主要实现挑战之一是需要修改 TLS/SSL 库以添加新需要的功能。

此更改是因为 HTTP/3 在加密内容方面与 HTTPS 不同。 使用较旧的 HTTPS 协议,只有数据本身受 TLS 保护,许多传输元数据可见。 在 HTTP/3 中,数据和传输协议都受到保护。 这听起来像是一项安全功能,而且确实如此。 但这样做是为了避免 HTTP/2 中存在的大量开销。 因此,对传输协议和数据进行加密实际上可以提高协议的性能。

HTTPS over TCP+TLS 与 QUIC 的比较。 TCP+TLS 在发送方和负载均衡器之间完全按顺序进行通信,包括三个初始往返,重复连接需要 200 毫秒,如果发送方以前从未与服务器通信,则需要 300 毫秒。相比之下,QUIC 在发送其主要数据并接收响应之前有一个初始发送,这意味着重复连接的开销为零,如果发送者以前从未与服务器交谈过,则只有 100 毫秒。

HTTP/3 对网络基础设施的影响

HTTP/3 并非没有争议。 主要关注点是网络基础设施。

客户端 HTTP/3

在客户端,UDP 流量受到严重的速率限制和/或阻塞是很常见的。 将这些限制应用于 HTTP/3 违背了协议的要点。

其次,HTTP 被监视和/或拦截是很常见的。 即使使用 HTTPS 流量,网络也会定期观察协议的明文传输元素,以确定它们是否应该放弃连接,以防止从特定网络或特定区域内访问某些网站。 在某些国家/地区,法律甚至规定某些服务提供商必须这样做。 HTTP/3 中的强制加密使这成为不可能。

这不仅仅是政府级别的过滤。 许多大学、公共图书馆、学校和家长关心的家庭积极选择阻止访问某些网站,或者至少保留访问过哪些网站的日志。 HTTP/3 中的强制加密使这成为不可能。

值得注意的,目前可以进行有限过滤。 这是因为服务器名称指示 (SNI) 字段(包含网站的主机名,但不包含路径、查询参数等)仍未加密。 但随着 ESNI(加密 SNI)的引入,这将在不久的将来发生变化,该 SNI 最近被添加到 TLS 标准中。

服务器端 HTTP/3

在服务器端,最好的做法是阻止任何不期望流量的端口和协议,这意味着服务器管理员现在需要为 HTTP/3 打开 UDP 443,而不是依赖于他们现有的 TCP 443 规则。

其次,网络基础设施可以使 TCP 会话具有粘性,这意味着即使路由优先级发生变化,它们也将始终路由到同一台服务器。 由于 HTTP/3 在无会话的 UDP 上运行,因此需要更新网络基础设施以跟踪特定于 HTTP/3 的连接 ID,这些连接 ID 未加密以帮助粘性路由。

第三,检查 HTTP 以检测滥用、监控常见安全问题、检测和防止恶意软件和病毒的传播等是很常见的。由于 HTTP/3 的加密,这是不可能的。 尽管如此,假设设备实现 HTTP/3 支持,拦截设备具有安全密钥副本的选项仍然是可能的。

最后,许多管理员反对必须管理更多的 SSL 证书,尽管现在有了 Let's Encrypt 等服务可用,这已经不是问题了。

在有广泛接受的、众所周知的解决方案来解决这些问题之前,我认为很多大型网络很可能会简单地阻止 HTTP/3。

HTTP/3 对 Web 开发的影响

在这方面没有太多可担心的。 HTTP/2 的流优先级和服务器推送功能仍然存在于 HTTP/3 中。 如果 Web 开发人员想要真正优化其网站性能,那么熟悉这些功能是值得的。

立即使用 HTTP/3

Google Chrome 或开源 Chromium 浏览器的用户已经准备好使用 HTTP/3。 HTTP/3 服务器的生产质量版本还有一段路要走——在撰写本文时,规范还没有完全确定。 但与此同时,有很多工具可供使用,谷歌和 Cloudflare 都已经将支持推向了他们的生产环境。

最简单的尝试方法是在 Docker 中使用 Caddy。 为此需要 SSL 证书,因此可公开访问的 IP 地址使事情变得容易。 步骤是:

  1. DNS 设置。 获取一个在 Internet 上运行的有效主机名,例如yourhostname.example.com IN A 192.0.2.1
  2. 球童文件创建。 它应该包含以下几行:
 yourhostname.example.com log stdout errors stdout ext .html .htm .md .txt browse gzip tls [email protected]
  1. 运行 Caddy: docker run -v Caddyfile:/etc/Caddyfile -p 80:80 -p 443:443 abiosoft/caddy --quic — 或在 Docker 外部, caddy --quic
  2. 在启用 QUIC 的情况下运行 chromium: chromium --enable-quic
  3. (可选)安装协议指示器扩展。
  4. 导航到启用 QUIC 的服务器,文件浏览器应该可见。

开发人员还可以使用以下有用的工具测试他们的服务器:

  • Keycdn 的 HTTP/2 测试
  • LiteSpeed 的 HTTP3Check
  • Qualys 的 SSL 服务器测试

谢谢阅读!


Google Cloud 合作伙伴徽章
作为 Google Cloud 合作伙伴,Toptal 为公司提供开发解决方案,并在其云之旅的每个阶段与他们合作。