HTTP/3:无处不在,又无处可用
HTTP/3 is everywhere but nowhere
2025年3月 作者:Tim Perry
HTTP/3 自 2016 年以来一直在开发中,而 QUIC(其底层协议)最早由 Google 于 2013 年推出。两者现在都已标准化,在 95% 的用户浏览器中得到支持,已经被 Cloudflare 的 32% 的 HTTP 请求使用,并且 35% 的网站声明支持(通过 alt-svc 或 DNS)在 HTTP Archive 数据集中。
我们开发了一个全新的 HTTP 版本,并且已经成功地将超过 1/3 的网络流量迁移到它!这是一个惊人的进步。
与此同时,QUIC 和 HTTP/3 都没有包含在任何主要语言的标准库中,包括 Node.js、Go、Rust、Python 或 Ruby。 Curl 最近 获得了支持,但它仍然是实验性的,并且在大多数发行版中被禁用。 某些语言有一些罕见的外部库,但它们都是实验性的和/或独立于其他核心网络 API。 尽管移动网络是 HTTP/3 的关键用例,但 Android 最流行的 HTTP 库 不支持。 像 Nginx 这样的流行服务器只有 实验性支持,默认情况下禁用,Apache 没有支持或发布支持计划,并且 Ingress-Nginx(可以说是最流行的 Kubernetes 反向代理)已经 放弃了所有 HTTP/3 支持计划,而是将一切都转移到一个全新的(尚未发布的)后续项目中。
实际上,很难指出任何完全支持 HTTP/3 的流行的开源工具:推广几乎还没有开始。
这似乎是矛盾的。 发生了什么?
我假设你对 HTTP/1.1 等、HTTP/2 和 HTTP/3 之间的差异有基本的了解。 如果您正在寻找更多背景信息,Daniel Stenberg(curl 的创始人兼首席开发人员)的 http2-explained 和 http3-explained 是一份优秀的指南。
Why do we need more than HTTP/1.1?
让我们简单回顾一下。 为什么这很重要? 谁在乎 HTTP/3 是否成功推广? 如果浏览器流量和大型 CDN 支持 HTTP/3,我们是否仍然需要在其他客户端或服务器实现中使用它?
例如,最近的一篇文章认为 HTTP/2 在负载均衡器之后没有太大意义。 简单来说,他们的观点是,HTTP/2 的主要优势在于多路复用,以避免延迟问题和 队头阻塞,而这些在局域网或数据中心内并不重要,因为往返时间 (RTT) 很低,并且可以无限期地保持长期的 TCP 连接打开。
你可以对 HTTP/3 提出同样的论点:这对网络浏览器和 CDN 的高延迟、多请求流量很有用,但在其他地方则无关紧要。
即使仅考虑 HTTP/1.1 与 HTTP/2,多路复用优势的现实也更加复杂:
- 响应的延迟不仅仅是网络 RTT:由于服务器处理导致的服务器响应缓慢将像网络延迟一样严重地阻塞您的 TCP 连接。
- 您的负载均衡器通常 不 与您的后端位于同一位置,例如,如果您通过地理分布的 CDN 提供所有内容,该 CDN 从其缓存提供大部分内容,但对于动态内容和缓存未命中,则回退到单独的应用程序服务器后端。
- 长期的 TCP 连接会死亡。 即使在数据中心内,网络也可能以一百万种方式发生故障,并且“保持活动”充其量只是绝望的恳求。 即使是 HTTP 本身也会强制执行此操作:在 HTTP/1.1 中,如果响应正文在半途中失败,则无法恢复,只能完全终止连接。
- 任何流量峰值都意味着您最终会以一种或另一种方式获得错误的 TCP 连接数:要么您需要始终有一个庞大的未使用池可用,要么您需要在流量峰值到来时打开大量新连接,因此需要处理 TCP 慢启动、RTT 和额外的 TLS 握手。
- 有很多流量不是网站 并且 不仅仅在数据中心内。 移动应用程序肯定会遇到网络延迟问题,API 服务器绝对会遇到可能阻塞开放连接的慢速端点,而 IoT 几乎完全由不可靠的网络和性能挑战组成。 所有这些情况都可以从 HTTP/2 和 HTTP/3 中获得价值。
除了多路复用之外,还有许多其他 HTTP/2 优势适用于负载均衡器和浏览器之外:
- HTTP 标头压缩(HTTP/2 中的 HPACK 和 HTTP/3 中的 QPACK)在许多情况下会显着减少流量,尤其 是在长期连接上,例如在内部基础设施中。 这在网络上很有用,但可以在移动和 IoT 场景中获得更大的提升,因为网络受限且不可靠。
- 双向 HTTP 请求和响应流(仅在 HTTP/2 和 HTTP/3 中可能)支持完全不同的通信模式。 最值得注意的是在 gRPC 中使用(对于大多数用法 需要 HTTP/2),这意味着客户端和服务器可以在同一“请求”中同时交换连续数据,其作用类似于 websocket,但在现有的 HTTP 语义中。
- 这两种协议都支持高级优先级支持,允许客户端向服务器指示请求的优先级,以更有效地分配处理资源并接收他们最迫切需要的数据。 这对于客户端很有价值,但在负载均衡器和服务器之间也很有价值:等待客户端的缓存未命中与可选的后台缓存重新验证具有非常不同的优先级。
以上只是针对 HTTP/2。 HTTP/3 在此基础上进一步改进,包括:
- 显着提高了对不可靠网络的弹性。 通过放弃 TCP 的严格数据包排序,HTTP/3 使连接中的每个流完全独立,因此一个流上丢失的数据包不会减慢另一个流的速度。
- 零往返连接初始化。 TLS1.3 允许在恢复与已知服务器的连接时进行零往返连接设置,因此您无需在发送应用程序数据之前等待 TLS 握手。 但对于 HTTP/1 和 HTTP/2,您仍然首先需要 TCP 握手。 使用 QUIC,您可以进行 0RTT TLS 握手,这意味着您可以连接到服务器并立即发送 HTTP 请求,而无需等待任何响应数据包,因此没有任何不必要的 RTT 延迟。
- 减少了流量大小、连接数和网络往返次数,从而可以减少客户端的电池使用量,并减少服务器的处理、延迟和带宽。
- 支持 连接迁移,允许客户端即使在其 IP 地址更改时也能继续相同的连接,并且理论上甚至支持使用多个地址的多路径连接(例如,同时使用 WiFi 和蜂窝网络的单个连接到服务器,以获得额外的带宽/可靠性)。
- 通过放弃 TCP 来改进网络拥塞处理:QUIC 可以使用 Bottleneck Bandwidth and RTT (BBR) 来通过主动检测网络状况来改进拥塞控制,在每个数据包中包含时间戳以帮助测量 RTT,改进了对数据包丢失的检测和恢复,更好地支持显式拥塞通知 (ECN) 以在数据包丢失之前主动管理拥塞,并且将来可能获得前向纠错 (FEC) 支持 在未来。
- 支持 WebTransport,一种提供双向全双工连接(类似于 WebSocket)的新协议,但支持多路复用流以避免队头阻塞,修复了各种旧版 WebSocket 限制(例如与 CORS 的不兼容),并允许流不可靠且无序 - 有效地在 Web 兼容的流连接中提供 UDP 风格的保证和更低的延迟。
除了理论之外,已经报告了一些具体的可衡量的好处。 例如,RequestMetric 运行了一些 详细的基准测试,显示了一些惊人的性能改进:
Fastly 分享了他们在现实世界中看到的 time-to-first-byte 的重大改进:
所有这些都非常棒。
现在该技术已标准化,在浏览器和 CDN 中得到广泛支持并经过彻底的实战测试,我认为所有开发人员都应该能够在他们的语言、服务器和框架中内置这些优势。
The two-tier web
然而,事实并非如此:尽管 HTTP/3 具有优势并且经常用于网络流量,但大多数开发人员今天无法轻松地开始端到端地使用 HTTP/3。 在这方面,HTTP/3 将互联网上长期存在的鸿沟鲜明地展现了出来。 如今,有两种非常不同的网络流量:
- 主要的浏览器加上一些非常特定的移动应用程序流量,其中一小部分经过微调和自动更新的客户端与一小部分非常大的服务器通信,尽可能多的流量由庞大的 CDN(Cloudflare、Akamai、Fastly、CloudFront)和/或重要的内部基础设施(Google、Meta、Amazon、Microsoft)处理。
- 其他所有人:后端 API 客户端和服务器、所有其他移动应用程序、每个较小的 CDN、没有 CDN 的网站、桌面应用程序、IoT、机器人和索引器以及抓取工具、小众 Web 浏览器、自托管家庭实验室、CLI 工具和脚本、学习网络协议的学生,等等。
让我们稍微简化一下,并将这两种情况描述为“超大规模 Web”和“长尾 Web”。 两者都建立在相同的基本标准之上,但它们具有非常不同的重点和需求,并且工具和平台也越来越不同。 这种情况已经存在很长时间了,但 HTTP/3 的现实使其痛苦地显现出来。
这些群体之间存在一些显着差异:
- 长尾流量大于超大规模流量。 67% 的网页请求直接提供,无需 CDN,并且在 2024 年 CDN 到 Cloudflare 的流量中,30% 是自动化的,60% 是 API 客户端。
- 几乎可以肯定的是,长尾世界被划分为不同的实现。 大多数最大的实现都是开源组织,可用的直接资金或全职工程能力相对较少,并且大部分工作由没有强制性中心方向或明确重点的志愿者完成。
- 超大规模世界由客户端和服务器端相对较少的关键利益相关者控制(您可以不用脱袜子就能数出相关的公司)。 这使他们能够快速有效地同意满足他们需求的标准 - 实际上是将每个实现的代表放在同一个房间里。
- 超大规模生态系统具有更集中的现金和动机。 这是由一些世界上最有价值的公司组成的一小部分参与者,其商业模式将网络性能的毫秒直接与其底线联系起来。
- 长尾完全依赖于开源实现和共享代码。 如果您想明天构建一个新的移动应用程序,显然不应该从构建 HTTP 解析器开始。
- 超大规模生态系统根本不担心访问开源实现。 他们拥有足够的工程资源和复杂的用例,从头开始构建协议的自定义实现是完全合理的。 Google.com 不会由带有默认设置的 Apache 模块提供服务,并且 Instagram 不会发送与 Hello-World 应用程序相同的 HTTP 库发出的请求。
- 超大规模的常青客户端、金钱和动机以及实现者与使用工具的业务之间的紧密联系相结合,意味着他们可以快速行动以快速构建、发布和迭代新方法。
- 长尾实现仅相对较少地更新(网络上有多少过时的 Apache 服务器?),并且维护人员是用户的一小部分,他们非常关心稳定性并避免重大更改。 长尾工具维护者 不能 只是快速行动并破坏事物。
您可以看到我正在描绘的图景。 这两个群体存在于同一个网络上,但方式截然不同。
其中一些听起来可能像是超大规模团伙是不义之徒。 我不是那个意思(好吧,是的,有一个更广泛的有趣的对话,但在这里严格讨论网络协议)。 具体来说,关于 HTTP/3,这是一项 极好的 工程工作,它通过不同大型组织之间令人惊讶的整洁的开源标准合作解决了网络上的实际问题。 这太棒了!
有 很多 人在使用这些公司构建的服务,他们对网络性能的痴迷每天都在提高大量实际人员的这些服务的质量。 这非常酷。
但是,如果每个其他服务器、客户端和开发人员也可以访问它,那将会更酷。 最值得注意的是,这意味着下一代 Web 技术正在由一个少数群体定义和构建,而更大的多数群体实际上现在无法访问该技术(尽管经过多年的标准化和开发),除非向该第一个少数群体的 CDN 付款以提供帮助。 不酷。
OpenSSL + QUIC
我认为超大规模/长尾的划分是根本原因,但这在下游造成了更多具体的难题,其中最值得注意的是 OpenSSL 对 QUIC 的处理方式。
OpenSSL 是最常用的 TLS 库,并且它是上述大量开源工具的基础库,因此它们对此的支持对于将 QUIC 和 HTTP/3 带到更广泛的生态系统至关重要。 已经有很多 关于 广泛的 公开的 讨论 关于 OpenSSL 对 QUIC 的处理方式,但作为一个快速总结:
- BoringSSL 早在 2018 年就发布了适用于 QUIC 实现的可用 API。
- OpenSSL 没有这样做,因此出现了各种 fork,如 QuicTLS,它提供了 OpenSSL 加上 BoringSSL 的 QUIC API。
- 在随后的多年中,QUIC 和 HTTP/3 实现(最值得注意的是 Quiche、msh3/msquic 和 nghttp3/ngtcp2)的生态系统建立在 BoringSSL 和这些 fork 之上。
- 此后,OpenSSL 缓慢地实现了与此生态系统无法直接使用的不兼容方法,客户端支持已在 OpenSSL 3.2 (2023) 中发布,而服务器支持即将发布在 OpenSSL 3.5 (2025) 中。
有些人会认为这是 OpenSSL 的一个重大错误,而我认为 OpenSSL 会认为 BoringSSL 的设计有缺陷和/或不适合 OpenSSL,并且值得花时间做好。
无论谁真正“正确”,这都在整个生态系统中造成了巨大的分裂。 Curl 对 不包括 OpenSSL 的现状有一个很好的概述:
OpenSSL 的方法在任何现有 QUIC 和 HTTP/3 实现的 TLS 部分中都无法轻松工作。 实际上,他们已经启动了另一列,但目前在 HTTP/3 和 QUIC 位置中没有兼容的实现。
这是一个值得注意的问题,因为对于大多数主要项目来说,放弃对 OpenSSL 的支持将是一项巨大且有问题的事情,这实际上意味着他们今天仍然无法发布内置的 QUIC 支持。 Node.js 最近 简要地讨论了 甚至完全删除 OpenSSL,转而使用 BoringSSL 或类似产品,但很明显这不切实际:这将是一项巨大的重大更改,没有其他替代方案提供相同级别的长期支持保证,并且 Node 和其他语言通常在 Linux 发行版等环境中发布,在这些环境中,它使用系统的共享 OpenSSL 实现,因此这也将在下游造成很大的麻烦。
这是网络上这两层组织的基本压力差异的一个例子:开源工具无法破坏这样的东西,并且长尾可用的库是分散且不协调的。 同时,超大规模可以快速且几乎单方面地做出决策,以设置今天适合其环境的实现,从而使他们能够获得新技术的好处,而不必过于担心每个人都使用的开源通用生态系统的状态。
What happens next?
我希望这能清楚地表明这里存在一个大问题:潜在的组织差异正在演变成互联网上技术的根本分裂。 有一种论点认为,尽管有好处,但长尾 Web 不需要 HTTP/3,因此他们可以忽略它,或者如果他们真的关心,可以使用具有内置支持的 CDN,并且超大规模实际上没有义务仅仅因为他们想在自己之间使用一些简洁的新技术而为我们其余的人提供方便的实现。
但这里的问题是,这些技术确实有真正具体的好处。 QUIC 是对替代方案的重大改进,尤其是在缓慢或不可靠的移动互联网上(例如,在发达国家/地区连接良好的办公室之外的任何地方)以及在连接之间漫游时。 有一些构建在其之上的技术,例如 WebTransport,它提供了额外的重要新功能和性能来取代 WebSocket。 将来会有更多依赖于 HTTP/3 的功能(请参阅 gRPC 如何构建在 HTTP/2 之上)。 再次:这里的技术很棒! 但是,如果这些好处没有均匀分布,并且只有一小部分组织及其客户可以访问,那将是一个挑战。
继续沿着这条路走下去可能会产生一些合理的严重后果:
- 在短期内,长尾 Web 与超大规模 Web 相比具有一个具体的缺点,因为 HTTP/3 和 QUIC 使超大规模站点更快、更可靠(尤其是在缓慢和移动互联网上)。
- 由为超大规模组织工作或在其工具和基础设施之上构建的开发人员使用的其他 Web 工具和组件(React 等)的复杂性将增加以匹配,将 HTTP/3 的好处视为理所当然并在此基础上向前发展,使其越来越与用例无关。
- 如果我们不小心,长尾用例和超大规模用例之间的差距将会扩大。 每种用例的新功能和工具都会出现,并且不会被另一种用例实现,并且工具将越来越分层。
- 如果仅超大规模技术被广泛使用但未实现,则构建与这些技术集成的工具将变得越来越困难。 如果您从头开始实现协议而不是仅仅实现 UI,则为 WebTransport 构建类似于 Postman 的客户端将更加困难。
- 您将开始看到缺乏 HTTP/3 支持用作触发验证码和 CDN 阻止的信号,就像今天的 TLS 指纹识别一样。 HTTP/3 支持可能会很快且轻松地成为检测许多非浏览器客户端的一种方式,从而将长尾客户端完全从现代 Web 中排除。
- 随着所有这些升级和自我强化,超大规模方面担心长尾的需求变得越来越不合理,并且生态系统可能会完全分层
所有这些都还很遥远,而且完全是假设! 我怀疑 其中一些 会在某种程度上发生,但存在广泛的可能性。 值得注意的是,这不仅仅适用于 HTTP/3:像这样的少数 CDN 和 Web 客户端的集中化和协调很容易在许多其他类型的技术改进中以类似的方式发挥作用。
至少对于 HTTP/3,我希望最终能有一个令人满意的解决方案来改善这种分裂,尽管我不知道它是否会及时到来以避免显着的后果。 许多 QUIC 和 HTTP/3 的外部库和实验性实现会随着时间的推移而成熟,并且我认为最终(我真的非常希望)OpenSSL QUIC API 分裂将会得到解决,以打开基于 许多 OpenSSL 的环境中的 QUIC 支持的大门,无论是通过适配器来支持这两种方法,还是通过直接支持 OpenSSL 模型的新 HTTP/3 和 QUIC 堆栈。 如果您有兴趣从事其中任何一项工作,并且我可以做任何事情来直接提供帮助或帮助资助这项工作,请 与我联系。
但是,这些都不会在今天发生,所以不幸的是,如果您想在您的应用程序中端到端地使用 HTTP/3,您可能在一段时间内会遇到困难。 关注此空间。
想同时调试 HTTP/1 和 HTTP/2 吗? 现在测试 HTTP Toolkit。 Web、Android、终端、Docker 等的开源一键式 HTTP(S) 拦截和调试。
建议更改此页面 在 GitHub 上
分享此帖子: [](https://httptoolkit.com/blog/http3-quic-open-source-support-nowhere/<https:/bsky.app/intent/compose?text=HTTP/3 is everywhere but nowhere%3Cbr%3E%3Cbr%3Ehttps://httptoolkit.com/blog/http3-quic-open-source-support-nowhere/>)
博客时事通讯 通过订阅以接收直接发送到您的收件箱的此类新帖子,成为 HTTP 和调试专家:
注册
Related content
http
2024年12月
ERR_PROXY_CONNECTION_FAILED errors with HTTP proxies
如果您正在使用像 HTTP Toolkit 这样的本地调试代理工具,您可能会在 Chrome 和其他类似应用程序中遇到可怕的“ERRPROXYCONNECTIONFAILED”错误。 这可能是一个非常令人沮丧且无用的错误! 但是只有几个可能的原因,而且通常很容易修复。
阅读更多
apis
2024年9月
Designing API Errors
当 API 的一切顺利时,生活非常简单:您请求资源,然后瞧,您就得到了它。 您触发一个过程,API 礼貌地通知您一切都按计划进行。 但是,如果出现问题怎么办? 好吧,这就是事情变得有点棘手的地方。 HTTP 状态代码就像急救箱:它们很方便,但无法解决所有问题。 它们让您大致了解哪里出了问题,这可以帮助许多工具和开发人员做出合理的假设,例如:
阅读更多
http
2024年2月
22 years later, YAML now has a media type
截至 2024 年 2 月 14 日,RFC 9512 正式注册“application/yaml”作为所有 YAML 内容的媒体类型,并将“+yaml”添加为所有基于 YAML 的更特定媒体类型的标准结构化后缀。 通过此注册,它现在包含在 IANA 维护的官方媒体类型列表中。 这种媒体类型(也称为 MIME 类型,来自它们最初为电子邮件附件元数据发明的)被大量使用,尤其是在 HTTP “Content-Type”标头中用于请求和响应,以及其他地方的各种文件元数据和处理逻辑中。 这些名称为应用程序提供了一个通用的词汇表,以便在传递数据时描述数据。 阅读更多 FOLLOW US opens in a new tabopens in a new tab opens in a new tab Product
Projects
Resources
Resources
Projects
Alternatives
Integrations