一、HTTP/3 到底解决了什么问题
每次聊到 HTTP/3,总有人问「上了能快多少」。这个问题本身就不太对,因为 QUIC 解决的从来不是「让页面变快」这一个目标,它解决的是几个具体的工程问题:建连慢、丢包时全队阻塞、移动网络切换时连接断掉。如果你的用户全在机房隔壁、网络干净得像实验室,上 HTTP/3 的收益接近于零,你只会多出一堆排查工作。
先说清楚 QUIC 的机制,后面所有配置都建立在这几点上。QUIC 跑在 UDP 之上,把 TLS 1.3 的握手和传输层握手合并成一次往返,首次建连是 1-RTT,会话恢复可以做到 0-RTT。它的流是独立的,一个流丢包不影响别的流,这跟 HTTP/2 在一条 TCP 连接上所有流共享同一个拥塞窗口完全不同。再加上连接 ID 机制,手机从 Wi-Fi 切到 4G 时连接可以迁移,不用重新握手。
这三条对个人站长的实际意义是:移动端用户的首次访问会明显更顺,弱网环境下大页面不会因为一个包丢了就整体卡住,跨境访问的握手开销能少一个 RTT。如果你的站点流量里有相当比例是移动端或者跨境,值得做;如果全是国内桌面端且已经在用 CDN,收益就要具体测。
二、先确认你的链路支持到哪一层
动手之前必须先搞清楚一件事:你的服务链路有几层。个人站长的典型结构是 用户 → CDN → 源站 Nginx。HTTP/3 可以在 CDN 边缘终结,也可以在源站终结,两层都开和只开一层,配置方式完全不同,而且这一层没搞清楚是最容易白忙的原因。
如果 CDN 支持 HTTP/3,那么用户到 CDN 这一段走 QUIC,CDN 到源站大概率还是 HTTP/1.1 或者 HTTP/2。这种情况下源站不需要装任何东西,只要在 CDN 控制台把开关打开、证书就绪即可。这是绝大多数个人站长该走的路,因为源站直接暴露 QUIC 端口需要 UDP 443 可达,而很多云服务器默认不放开。
如果要在源站自己开,先确认三件事。第一,nginx -V 的输出里有没有 --with-http_v3_module,没有这个参数就是没编译进去,装再多配置也没用。第二,系统能不能让 UDP 443 进来,云厂商的安全组要单独放行 UDP,只放行 TCP 是最常见的疏漏。第三,前面有没有防火墙或者负载均衡把 UDP 挡了。
nginx -V 2>&1 | tr ' ' '\n' | grep -E 'http_v3|quic|openssl'
ss -ulnp | grep 443
curl -s -I --http3 https://www.example.com/三条命令分别回答:模块有没有编译、端口有没有监听、客户端能不能通。第三条如果报 curl 不支持 http3,那说明是本地 curl 版本太老,得换一个带 HTTP/3 的版本才能测。
三、Nginx 侧的最小配置
假设模块已经就绪,配置本身不长。关键是在 server 块里监听同一个 443 端口的 UDP,并把 ssl 相关参数换成 quic 的:
server {
listen 443 ssl;
listen 443 quic reuseport;
http2 on;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
location / {
root /var/www/html;
}
}几个要点值得单独说。第一,TCP 的 443 和 UDP 的 443 必须同时监听,不能只留 QUIC,因为大量客户端还不支持 h3,全靠 Alt-Svc 协商降级到 h2。第二,reuseport 在多 worker 场景下是必须的,否则 UDP 包会被内核分到不固定的 worker 上,导致 QUIC 连接异常。第三,add_header Alt-Svc 这一行是整个机制的开关,它告诉浏览器「本站也支持 h3,下次可以直接试」。没有这一行,浏览器永远不知道你开了 HTTP/3。
Alt-Svc 的 ma 是有效期,单位秒。设得太短浏览器会频繁重新协商,设得太长则在你关掉 HTTP/3 之后浏览器还会继续试一段时间然后失败重试,造成几百毫秒的延迟。86400 一天是个平衡点。如果你要下线 h3,正确做法是先把 ma 改短,等一天后再关端口,而不是直接关掉。
另外注意 `http2 on;` 这个写法是 Nginx 1.25.1 之后的新语法,更早的版本要写成 listen 443 ssl http2;。写成旧语法在新版上会报错,反过来也一样,这一步出问题的人不少。
四、验证:怎么确认真的走的是 h3
配置 reload 之后不要急着相信,按顺序验证四件事。
第一步看端口。UDP 443 有没有真的监听上,ss -ulnp 里必须出现 nginx 的进程。如果没有,先查配置有没有语法错误,再看是不是被 SELinux 或者容器的端口映射挡住了。
第二步看响应头。用普通 curl 访问首页,响应头里应该有 Alt-Svc。这一步能过,说明浏览器已经知道了 h3 的存在。
curl -s -I https://www.example.com/ | grep -i alt-svc第三步做实际握手。用支持 HTTP/3 的 curl 直接请求,加 --http3 参数,看返回的协议版本。如果能拿到 200 且没有报错,说明整条 UDP 链路通畅。
第四步才是浏览器实测。Chrome 地址栏打开站点,F12 到 Network 面板,把 Protocol 列调出来,看请求是不是 h3。如果显示 h2,等几秒刷新一次,因为 Alt-Svc 缓存需要一次访问才会生效。如果一直是 h2,打开 chrome://net-internals/#quic 看有没有被禁用。
这里有一个很常见的假象:有些 CDN 会在响应里回一个 Alt-Svc,但实际边缘节点并没有开 QUIC,浏览器试了之后降级回 h2,用户完全感知不到异常,你却在控制台看到「已开启」。所以最终判据只能是第四步,看到 Protocol 列真的显示 h3。
五、踩坑清单:这五种情况会让 h3 直接不可用
第一种是云安全组只放了 TCP。这是最高频的原因。UDP 443 没放行,浏览器试 h3 会超时,然后降级,用户多等几百毫秒,你完全看不出来。
第二种是中间设备丢 UDP。部分企业防火墙、家用路由、运营商网络会对 UDP 443 做限速甚至直接丢弃。这种情况你没法控制,Alt-Svc 机制本身就是为了兜住它,降级到 h2 是正常的,不算故障。
第三种是 MTU 问题。QUIC 要求路径 MTU 至少 1200 字节,某些隧道网络(VPN、GRE)下 MTU 被压到 1280 以下,握手包过不去。表现为部分用户 h3 一直连不上,而这些用户往往集中在某个网络环境里。可以在服务端把初始包大小调到 1200 以求稳。
第四种是多个 server 块抢同一个 UDP 端口。reuseport 加了但配置里有两个 server 监听 443 quic,内核分配不均导致连接时好时坏。检查方法是 reload 之后连续请求十几次看成功率。
第五种是 CDN 与源站同时开了 h3 但证书不一致。边缘用一张证书,源站用另一张,QUIC 握手时 SNI 对不上直接失败。这种情况只能在 CDN 侧终结,源站关掉 QUIC。
六、有了 HTTP/3 之后,哪些老优化可以撤
这一节是我觉得最有价值的部分,因为很多人上了 h3 之后还在用一套为 HTTP/1.1 时代准备的优化,白白增加了复杂度。
域名分片可以撤了。HTTP/1.1 时代浏览器对同一域名只开六个连接,所以把静态资源拆到 static1、static2、static3 上能提升并发。HTTP/2 的多路复用已经让这个技巧失效,HTTP/3 更是完全没必要。分片反而增加了 DNS 查询和连接建立的开销。如果你的站点还有这种配置,可以合并回去。
雪碧图可以撤了。把十几张小图标拼成一张大图,是为了减少请求数。但 h3 的请求开销极低,而且雪碧图会导致任何一张小图改动都要重新下载整张图。改成独立的 SVG 或者小 WebP,缓存粒度更细,改起来也更方便。
内联关键 CSS 的必要性下降了,但没有消失。内联是为了省掉一次阻塞渲染的请求,h3 下这个请求变快了,但依然存在一个 RTT 的等待。首屏 CSS 内联依然值得做,只是不必再把所有 CSS 都塞进 HTML。
预连接可以精简。preconnect 在 h3 下依然有用,但优先级降低了,因为建连本身变快了。把第三方域名的 preconnect 从五六个砍到一两个真正关键的,剩下的用 dns-prefetch 就够。
但有一件事不能省:缓存头。h3 再快也要走缓存验证。静态资源的长缓存加内容哈希命名,在任何协议版本下都是收益最高的一件事,别因为换了新协议就忽略它。
七、什么时候不该上 HTTP/3
最后说几句泼冷水的话,因为并不是所有站都适合。
如果你的流量主体在国内桌面端,且已经接入支持 h3 的 CDN,那么在 CDN 控制台打开开关就够了,源站完全不用折腾。这种情况几乎没有成本,值得做。
如果你的源站是单台小机器、前面没有 CDN、用户分布很散,那自己开 h3 的收益可能抵不上维护成本。UDP 443 暴露在公网上会带来新的攻击面,包括 QUIC 握手放大攻击和各类协议实现漏洞,你需要额外关注 Nginx 的版本更新。
如果站点还在 HTTP/1.1,先别急着跳到 h3,把 h2 开起来。h2 相对 h1 的收益比对 h1 直接上 h3 的边际收益大得多,而且排查工具成熟得多。
八、小结
HTTP/3 的价值在弱网和移动场景,配置的核心是「TCP 和 UDP 双监听 + Alt-Svc 声明 + 云安全组放行 UDP」,验证的唯一可信判据是浏览器 Network 面板里真的显示 h3。上了之后顺手清理掉为 h1 时代准备的域名分片和雪碧图,但缓存策略这件事永远不要省。对大多数个人站长来说,让 CDN 干这件事、源站保持简单,是性价比最高的选择。