
作者:Robin Marx
翻译:Alex
技术审校:刘连响
Robin 讲 HTTP/3 #001#
写在前面
前段时间,LiveVideoStack 采访了 IETF 贡献者、HTTP/3 和 QUIC 工作组成员 Robin Marx,在采访中,他向我们介绍了 HTTP/3 和 QUIC 带来的优势、设计 HTTP/3 时所遇到的挑战、HTTP/3 的采用问题以及他对互联网未来发展的看法等等(对话 Robin Marx:HTTP/3 和 QUIC 将带来重大机遇和挑战)。
许多读者在阅读 Robin 的采访后表示意犹未尽,想了解和学习更多关于 HTTP/3 和 QUIC 的知识。恰巧,Robin 去年在_Smashing Magazine_上发表了一系列讲解 HTTP/3 和 QUIC 的文章(原文链接:https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/)。因此,我们向_Smashing Magazine_和 Robin 本人申请翻译该系列文章,并在未来一段时间依次将其发表在 LiveVideoStack 的平台上,以飨读者。
在这里,我们要特别感谢_Smashing Magazine_和 Robin 的慷慨授权。

所以在本文开始前,我们要向先大家介绍一下_Smashing Magazine_和 Robin Marx。
Smashing Magazine 既是一家技术网站,同时也是电子书出版商,专注于为网络开发人员和网页设计师提供高质量内容和专业资源。它由 Sven Lennartz 和 Vitaly Friedman 于 2006 年在德国创立。自 2012 年起,它开始在欧洲和北美举办网页设计会议 —— Smashing Conference。
Smashing Magazine(https://www.smashingmagazine.com/)
截至 2017 年 5 月,_Smashing Magazine_每月的页面浏览量约为 300 万,全球 Twitter 关注者接近 100 万,并拥有 29.5 万名 Facebook 粉丝,25.2 万名 Feedly 订阅者,以及超过 23 万名 newsletter 订阅者。_Smashing Magazine_是最活跃和最大的 Web 开发资源出版商之一(数据来自 Wikipedia)。
Robin Marx
Robin Marx: IETF 贡献者、HTTP/3 和 QUIC 工作组成员。2015 年,作为 PhD 的一部分,Robin 开始研究 HTTP/2 的性能,这使他后来有机会在 IETF 中参与 HTTP/3 和 QUIC 的设计。在研究这些协议的过程中,Robin 开发了 QUIC 和 HTTP/3 的调试工具(被称为 qlog 和 qvis),目前这些工具已经使来自世界各地的许多工程师受益。今年 8 月,Robin 将入职 Akamai,成为一名解决方案架构师 / 网络性能专家。
速览:经过近五年的开发,新的 HTTP/3 协议终于接近尾声。虽然作为实验性功能的早期迭代早已可用,但 HTTP/3 的可用性和使用将在 2021 年进一步增加。所以到底什么是 HTTP/3? 为什么在 HTTP/2 之后,这么快我们就需要 HTTP/3?你应该(或可以)如何使用它?尤其是,HTTP/3 如何提升网络性能?让我们来一一了解。
你也许已经读过一些相关博客或者听过这方面的演讲,并认为自己知道上述问题的答案。你可能听过这样的说法:“当丢包时,HTTP/3 比 HTTP/2 快多了” 或 “HTTP/3 连接延迟更低,设置时间更短” 或 “HTTP/3 能够更快地发送数据,而且可以并行发送更多资源”。
这些说法和文章通常略过了关键的技术细节、缺乏对于技术细微差别的描述,而且并不完全正确。它们经常将 HTTP/3 描述为一场性能革命,但其实它是一次更加 “温和(但依然有用!)” 的演进。这些关于 HTTP/3 的表述很危险,因为这一新的协议将可能无法在实际中符合这些高期望。我担心,很多人最终会对 HTTP/3 感到失望,而新人将困惑于这些盲目存在的错误信息。
我之所以担心,是因为 HTTP/2 也经历过同样的处境。当初 HTTP/2 被誉为一场惊人的性能革命,并拥有服务器推送(server push)、并行流(parallel stream)和优先级(prioritization)等激动人心的新功能。我们将停止打包资源、停止在多个服务器上 sharding 资源、并在很大程度上简化页面加载过程。只需轻轻一按,网站就能神奇地快上 50%!
五年后,我们知道,服务器推送在实际中并未起作用,并行流和优先级也经常无法得到很好的实现,因此(减少的)资源打包甚至是 sharding 在某些情况中依然是常用的做法。
同样,其他调整协议行为的机制,比如预加载,通常含有隐蔽的细节和 bug,导致它们很难正确使用。
因此,我认为对于 HTTP/3 来说,阻止这些错误信息和不切实际的期望的传播很重要。
在本系列的文章中,我将讨论新协议(尤其是它的性能特点)的更多细微差别。我将向你说明,虽然 HTTP/3 确实拥有一些备受期待的新概念,但遗憾的是,对于大部分网页和用户来说(除了对其中一小部分非常关键),它们的影响将很可能相对有限。HTTP/3 的设置和使用(正确)也很具有挑战性,所以配置新协议时一定要多加注意。
第一部分:HTTP/3 的历史和核心概念
这一部分针对不了解 HTTP/3 和其他一般协议的读者,主要介绍基础知识。
第二部分:HTTP/3 性能特点
这一部分更深入,技术内容更多。已经了解基础知识的读者可以从这里开始。
第三部分:实用的 HTTP/3 部署选项
系列中的第三部分解释了自己部署和测试 HTTP/3 所遇到的挑战。它详细解释了你应如何或者是否更改网页或者资源。
注意: 本系列主要目标读者是那些还没有深入了解协议知识并想进行学习的 Web 开发者。此外,本系列文章包含了丰富的技术内容和很多外部资源链接,同样也适用于感兴趣的高阶读者。
我们为什么需要 HTTP/3?
我经常遇到的一个问题是:“在 HTTP/2(在 2015 年才标准化)之后,我们为什么这么快就需要 HTTP/3?” 这的确很奇怪,直到你意识到,首先我们并不是真的需要一个新的 HTTP 版本,而是需要升级 TCP(传输控制协议,Transmission Control Protocol )。
TCP 是向 HTTP 等协议提供可靠性和按顺序发送等关键服务的主要协议。这也是我们一直和许多并发用户一起使用互联网的原因,因为 TCP 巧妙地将每个用户的带宽限制在他们的公平份额之内。
你知道吗?
使用 HTTP (S) 时,你同时也在使用除 HTTP 之外的几个协议。协议栈中的每个协议都有其自身的特点和功能(见下方图片)。比如,HTTP 处理 URL 和数据解析;TLS(Transport Layer Security)确保安全加密;TCP 通过重传丢包实现可靠数据传输;IP 在中间的不同设备(中间件)上将数据包从一个端点传送到另一个端点。
这种相互叠加的协议 “分层” 可以轻松重用它们的特性。高层协议(如 HTTP)无需重新实现复杂特性(如加密),因为底层协议(如 TSL)已经具备加密特性。除此之外,互联网上大多数内部使用 TCP 的应用可以确保它们的数据获得完整传输。正因如此,TCP 成为互联网上最广泛使用和部署的协议之一。
HTTP/2 vs.HTTP/3 协议栈对比
几十年来,TCP 一直是网络的基础,但在 2000 年后期开始初现老态。它预期中的替代品 —— 新型传输协议 QUIC,在很多关键处都与 TCP 大不相同,所以直接在其上运行 HTTP/2 将非常困难。因此,HTTP/3 本身其实是对 HTTP/2 相对较小的更改,从而与新的 QUIC 协议(包括了大部分令人激动的新特性)兼容。
之所以需要 QUIC,是因为 TCP 在互联网早期时就已存在,但在开发它时并没有考虑到最大效率。比如,TCP 需要 “握手” 建立新的连接。这么做的目的是确保客户端和服务端都存在,且它们愿意并能够交换数据。TCP 还需要一个完整的 RTT,才能在连接上进行其他操作。如果客户端和服务端的地理位置相距较远,那么每个 RTT 都要超过 100 毫秒,因此会导致明显的延迟。
其次,即使实际上我们正在通过 TCP 同时传输几个文件(比如,当下载包含多个资源的网页时),TCP 依然将所有它传输的数据都看作单一 “文件” 或者 “字节流”。这意味着如果包含单一文件的 TCP 数据包丢失,所有其他文件也将延迟,直到那些数据包被恢复。
上述现象被称为 “队头阻塞 [head-of-line (HoL) blocking]”。虽然这些低效操作在实际中可控(不然,我们也不会使用 TCP 长达三十余年),但它们明显影响到了 HTTP 等高层协议。
随着时间的推移,为了改进这些情况甚至推出新的性能特性,我们尝试发展和升级 TCP。比如,TCP 快速打开(TFO,TCP Fast Open)使高层协议从最开始就可以发送数据,而避免了握手次数进而提升了效率。另一个是多通路 TCP(MultiPath TCP),其中的原理是:你的移动手机通常包括 Wi-Fi 和(4G)蜂窝连接,所以为什么不同时使用它们来增加吞吐量和鲁棒性呢?
实现这些 TCP 扩展并不困难。不过,将它们实际大规模部署在互联网上却极具挑战。因为,TCP 太流行了,几乎每个连接它的设备都有自己的 TCP 实现。如果这些实现过于陈旧、缺乏更新或者充满 bug,那么在实际中,这些 TCP 扩展将无法使用。换句话说,为了在实际中可以使用,所有实现都需要了解这些扩展。
如果只是涉及终端用户设备(比如你的电脑或者 Web 服务器),上文所述不会成为太大的问题,因为这些设备可以相对轻松地通过手动升级。但是,客户端和服务端之间存在许多其他设备,它们有其自己的 TCP 代码(其中包括防火墙、负载均衡器、路由器、缓存服务器和代理等)。
想要升级这些中间件,通常非常困难,而且有时它们所接受的操作也更加严格。比如,如果设备是防火墙,它可能被配置为阻止所有包含(未知)扩展的流量。实际上事实证明,大量活跃的中间件都认定 TCP 不再适用新的扩展。
因此,要使足够的 TCP 实现获得更新(从而可以大规模使用这些扩展)将耗费多年甚至超过十年的时间。也可以说,TCP 的发展在实际中不可行。
所以很明显,我们需要一个 TCP 的替代协议,而不是直接升级 TCP 来解决问题。然而,由于十分复杂的 TCP 特性及其多种不同的实现,从零开始开发新的、更好的协议将会是一项艰巨的任务。因此,在 2010 初,这项工作被推迟了。
归根结底,这些问题不仅存在于 TCP,也同时存在于 HTTP/1.1。我们选择将这项工作拆分:先 “修理” HTTP/1.1,使其成为现在的 HTTP/2;完成之后,开始开发替换 TCP 的协议,也就是现在的 QUIC。最初,我们希望在 QUIC 之上直接运行 HTTP/2,但在实际中这将造成各类实现过于低效 [主要是因为特性重复(feature duplication)]。
为了与 QUIC 兼容, HTTP/2 在几个关键领域进行了调整。这个调整的版本最终被命名为 HTTP/3(而不是 HTTP/2-over-QUIC),以此命名主要是从市场推广和理解清晰的角度考虑。因此,HTTP/1.1 和 HTTP/2 之间的差异要比 HTTP/2 和 HTTP/3 的差异大很多。
要 点
本文的关键要点:我们真正需要的并不是 HTTP/3,而是 “TCP/2”,只不过在这个过程中我们 “免费” 收获了 HTTP/3。HTTP/3 中这些令人激动的主要特性(快速连接设置、减少的队头阻塞、连接迁移等等)实际上都是来自 QUIC。
References:
https://www.ctrl.blog/entry/http2-push-chromium-deprecation.html
https://github.com/andydavies/http2-prioritization-issues
https://twitter.com/yoavweiss/status/1254650804524507136
https://twitter.com/zachleat/status/1055219667894259712
https://speeder.edm.uhasselt.be/webist/files/h2bestpractices_RobinMarx_WEBIST2017.pdf
https://twitter.com/programmingart/status/1351557858354225159
https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
https://www.rfc-editor.org/rfc/rfc9000.html
https://squeeze.isobar.com/2019/04/11/the-sad-story-of-tcp-fast-open/
https://developer.mozilla.org/en-US/docs/Glossary/TCP_handshake
https://hpbn.co/http2/#design-and-technical-goals
最后,我们会将所有文章收录在 “Robin 讲 HTTP/3” 系列中,欢迎大家订阅。