Language:Chinese VersionEnglish Version

HTTP/3 已到来。大多数人不会注意到。

HTTP/3 自 2022 年 6 月起已成为 RFC 标准。到 2026 年初,超过 30% 的网络流量将通过 HTTP/3 运行。Cloudflare、Google 和 Meta 已在生产环境中使用 HTTP/3 多年。然而,与我交谈的大多数后端工程师无法告诉你 QUIC 在协议层面实际改变了什么,或者他们是否应该关心。诚实的答案是:这取决于你的用例,对许多人来说,影响比炒作所暗示的要小。

让我带你了解 HTTP/3 和 QUIC 实际改变了什么,什么保持不变,以及真正的生产优势(和头痛问题)出现在哪里。

QUIC 实际是什么

QUIC(快速 UDP 互联网连接)是一种传输协议,取代了 TCP 成为 HTTP/3 的基础。关键架构变化是 QUIC 运行在 UDP 而不是 TCP 上,并且在用户空间而非内核中处理可靠性、排序和拥塞控制。

以下是协议栈对比:

层级 HTTP/2 HTTP/3
应用层 HTTP/2 HTTP/3
安全层 TLS 1.2/1.3 TLS 1.3(内置在 QUIC 中)
传输层 TCP QUIC
网络层 IP UDP/IP

需要理解的关键是,QUIC 不是”附加了可靠性的 UDP”。它是一个专门构建的传输协议,碰巧使用 UDP 作为其交付机制。它包含自己的流控制、拥塞控制、丢失恢复和多路复用——所有这些都是从零开始设计的,借鉴了过去二十年 TCP 优化的经验教训。

三个实际改变的地方

1. 连接建立更快

TCP+TLS 需要两到三个往返行程才能发送第一个字节的 application 数据:一个用于 TCP 握手,一个(或两个)用于 TLS。QUIC 将传输和密码学握手合并为一个往返行程。对于重复连接,QUIC 支持 0-RTT 恢复——客户端可以在第一个数据包中发送 application 数据。

# TCP + TLS 1.3 连接建立:
# RTT 1: TCP SYN → SYN-ACK
# RTT 2: TLS ClientHello → ServerHello + Finished
# RTT 3: 第一个 application 数据
# 总计:第一个数据前需要 2 RTT(TLS 1.3 0-RTT 需要 1 RTT)

# QUIC 连接建立:
# RTT 1: QUIC Initial(包含 TLS ClientHello)→ 响应
# 总计:第一个数据前需要 1 RTT(恢复时为 0 RTT)

# 实际上,在 100ms RTT 连接上:
# HTTP/2:200-300ms 连接设置
# HTTP/3:100ms 连接设置(恢复时为 0ms)

这对高延迟连接(移动网络、卫星互联网、远离服务器的用户)的用户最为重要。对于快速有线连接且 RTT 低于 10ms 的用户,节省的时间可以忽略不计。

2. 队头阻塞问题已解决(大部分)

HTTP/2 最大的架构缺陷在于 TCP 层的队头阻塞(HOL)。尽管 HTTP/2 可以在单个连接上多路复用多个流,但 TCP 将所有这些流视为单个字节流。如果单个 TCP 数据包丢失,该连接上的所有流都会停滞,直到丢失的数据包被重传。

QUIC 通过在协议中将流实现为独立实体来解决这个问题。如果属于流 5 的数据包丢失,只有流 5 会停滞。流 1-4 和流 6+ 继续正常处理。

# 基于 TCP 的 HTTP/2:数据包丢失影响所有流
# 连接有 6 个多路复用流
# 流 3 的数据包丢失
# 结果:所有 6 个流都阻塞直到重传
# 用户体验:整个页面短暂冻结

# 基于 QUIC 的 HTTP/3:数据包丢失仅影响受影响的流
# 连接有 6 个多路复用流
# 流 3 的数据包丢失
# 结果:只有流 3 阻塞;流 1,2,4,5,6 继续正常
# 用户体验:一个资源加载稍慢,其他不受影响

这是一个真实可测量的改进——但仅在数据包丢失的情况下。在干净、低损耗的网络(有线连接、良好的 WiFi)上,差异很小,因为队头阻塞首先很少发生。

3. 连接迁移有效

TCP 连接由四元组标识:源 IP、源端口、目标 IP、目标端口。当您的手机从 WiFi 切换到蜂窝网络时,所有 TCP 连接都会中断,因为源 IP 发生了变化。进行中的每个 HTTP 请求都会失败,必须建立新的连接。

QUIC 连接由独立于网络路径的连接 ID 标识。当底层 IP 地址更改时,连接继续使用新地址。这对于经常切换网络的移动用户特别有价值。

未改变的内容

以下是营销材料往往省略的内容:

您的应用程序代码相同

HTTP/3 不改变 HTTP 语义。头部、方法、状态码、请求/响应体——与 HTTP/2 完全相同。如果您的后端通过反向代理提供 HTTP 响应(应该这样做),您可能不需要更改一行应用程序代码。

# 无论通过 HTTP/2 还是 HTTP/3 服务,您的 API 代码完全相同
from fastapi import FastAPI

app = FastAPI()

@app.get("/api/users/{user_id}")
async def get_user(user_id: int):
    return {"id": user_id, "name": "Alice"}

# 传输协议由您的反向代理(Caddy、nginx 等)处理,
# 而不是您的应用程序代码。

服务器端性能基本不变

HTTP/3 主要改进的是客户端与服务器之间的连接,而不是服务器端处理。如果你的瓶颈在于数据库查询、业务逻辑或上游服务调用,HTTP/3 不会让你的 API 更快。改进之处在于连接建立时间和对丢包的弹性恢复能力——这两者都属于网络层的问题。

在良好网络上的吞吐量基本相同

在低延迟、低丢包的网络中,HTTP/3 和 HTTP/2 在批量数据传输方面的表现几乎相同。QUIC 的拥塞控制算法仍在成熟过程中,在某些场景下表现可能略逊于经过 40 年调优的高度优化的 TCP 栈。

在生产环境中部署 HTTP/3

选项 1:CDN/代理处理(推荐)

如果你使用 Cloudflare、AWS CloudFront、Fastly 或任何主要 CDN,HTTP/3 可能已经为你的用户启用。CDN 从客户端终止 HTTP/3 连接,并通过 HTTP/2 或 HTTP/1.1 代理到你的源服务器。这是阻力最小的路径,适用于大多数应用。

选项 2:Caddy(最简单的自托管)

Caddy 开箱即支持 HTTP/3,无需额外配置:

# Caddyfile - HTTP/3 默认启用
api.example.com {
    reverse_proxy localhost:8080
}
# 就是这样。Caddy 自动处理 ACME 证书、HTTP/2 和 HTTP/3。

选项 3:Nginx(需要额外步骤)

Nginx 在 1.25 版本中添加了实验性的 HTTP/3 支持。它需要使用支持 QUIC 的 TLS 库进行编译:

# 带 HTTP/3 的 nginx.conf
server {
    listen 443 ssl;
    listen 443 quic reuseport;      # QUIC 监听器
    http2 on;

    ssl_certificate     /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;

    # 通过 Alt-Svc 头部宣告 HTTP/3 支持
    add_header Alt-Svc 'h3=":443"; ma=86400';

    # 启用 0-RTT(存在安全注意事项)
    ssl_early_data on;

    location / {
        proxy_pass http://backend:8080;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

Alt-Svc 头部至关重要。浏览器最初通过 HTTP/2 连接,只有在收到此头部后才会升级到 HTTP/3。首次页面加载将始终使用 HTTP/2;后续访问将使用 HTTP/3。

运维难题

UDP 防火墙

许多企业防火墙和网络中间设备会阻止或限速 443 端口的 UDP 流量。这意味着相当比例的用户可能永远无法使用 HTTP/3。浏览器会优雅地回退到 HTTP/2,但这意味着你的实际 HTTP/3 采用率将始终低于预期。

# 检查你的网络是否可以访问 HTTP/3
curl --http3 -I https://your-domain.com

# 如果超时,说明你的网络阻止了 QUIC。
# 浏览器将静默回退到 HTTP/2。

调试更困难

每个网络调试工具都能很好地理解 TCP 流量。QUIC 流量在传输层(而不仅仅是应用层)进行加密,这意味着像 tcpdump 和 Wireshark 这样的工具需要 QUIC 专用的分析器和 SSLKEYLOGFILE 导出功能来检查流量:

# 捕获 QUIC 流量用于调试:
# 1. 设置 SSLKEYLOGFILE 环境变量
export SSLKEYLOGFILE=/tmp/quic-keys.log

# 2. 捕获流量
tcpdump -i eth0 -w /tmp/quic.pcap 'udp port 443'

# 3. 在 Wireshark 中打开并使用密钥日志文件
# 编辑 > 首选项 > 协议 > TLS > (预)主密钥日志文件名
# 指向 /tmp/quic-keys.log

负载均衡复杂性

TCP 负载均衡器使用四元组在连接级别工作。QUIC 连接迁移意味着四元组可以在连接中途改变,这会破坏传统的 L4 负载均衡。您需要能够检查 QUIC 头部中连接 ID 的 QUIC 感知负载均衡器:

# HAProxy 2.6+ 支持 QUIC
frontend https
    bind :443 ssl crt /etc/ssl/cert.pem alpn h2,http/1.1
    bind quic4@:443 ssl crt /etc/ssl/cert.pem alpn h3
    
    default_backend servers

backend servers
    server s1 10.0.1.10:8080 check
    server s2 10.0.1.11:8080 check

您需要关注吗?

以下是我按用例给出的诚实评估:

用例 HTTP/3 影响 优先级
面向全球受众的内容密集型网站 在移动设备/高延迟网络上有明显改善 通过 CDN 启用(轻松获胜)
为移动应用提供服务的 API 更快的连接建立,更好的网络切换 如果 CDN 支持则值得启用
内部微服务通信 可忽略不计(低延迟、低损耗网络) 无需费心
实时应用(游戏、视频) 连接迁移很有价值 直接评估 QUIC
企业 B2B API 客户端可能在阻止 UDP 的防火墙后面 低优先级,确保 HTTP/2 降级功能

对于大多数后端工程师来说,可操作的要点是:在您的 CDN 或反向代理层启用 HTTP/3,确保 HTTP/2 降级功能正常工作,然后继续前进。该协议在透明化方面做得最好,而它产生显著差异的情况(高延迟移动用户、损耗网络)已由浏览器和 CDN 提供商自动处理。

HTTP/3 是对 Web 平台的真实改进。它也不是早期炒作所暗示的革命。最大的胜利不是速度——而是弹性。对于大多数应用程序来说,这种弹性是由基础设施层免费提供的,无需对应用程序代码进行任何更改。

By Michael Sun

Founder and Editor-in-Chief of NovVista. Software engineer with hands-on experience in cloud infrastructure, full-stack development, and DevOps. Writes about AI tools, developer workflows, server architecture, and the practical side of technology. Based in China.

Leave a Reply

Your email address will not be published. Required fields are marked *

You missed