HTTP/2 与 HTTP/3:升级之后到底快在哪

升级到 HTTP/2 基本是零成本的收益(改一个配置指令),HTTP/3 则要看网络环境。这篇讲清楚它们解决了什么、怎么开、怎么验证。

一、HTTP/1.1 的问题

问题说明
队头阻塞一个连接同一时刻只能处理一个请求
连接数限制浏览器对同一域名最多 6 个并发连接
头部冗余每个请求都带完整的 Cookie、UA 等

以前的应对办法(现在都不需要了):

  • 域名分片(把资源分散到多个子域)—— HTTP/2 下是反优化
  • 合并 CSS/JS 成一个文件 —— HTTP/2 下反而有害(缓存粒度变粗);
  • 图片 base64 内联 —— 同上。

二、HTTP/2 的三个改进

特性说明
多路复用一个连接上并发传输多个请求,互不阻塞
头部压缩HPACK 算法,减少重复头部
二进制分帧解析更高效
服务端推送可主动推资源(实践中较少用,且已不被推荐

三、Nginx 开启

nginx
server {
    listen 443 ssl;
    http2 on;                 # Nginx 1.25.1+ 的新写法

    # 老版本(1.24 及以下)写法:
    # listen 443 ssl http2;

    ssl_certificate     /etc/letsencrypt/live/www.bzii.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.bzii.cn/privkey.pem;
}
bash
sudo nginx -t && sudo systemctl reload nginx

注意:如果同一端口上既有 http2 on 又有 listen ... http2(老写法),Nginx 会警告重复。二选一。

前提

  1. 必须 HTTPS(浏览器只在 TLS 上支持 h2);
  2. OpenSSL 版本支持 ALPN(1.0.2+,现在都满足);
  3. 检查 Nginx 编译是否含 http_v2 模块:
bash
nginx -V 2>&1 | grep -o "http_v2"

四、HTTP/3 是什么

HTTP/3 = HTTP 语义 + QUIC 传输协议:

HTTP/2HTTP/3
传输层TCPUDP(QUIC)
加密TLS 独立内置在 QUIC
握手TCP + TLS 分开1-RTT(甚至 0-RTT)
队头阻塞传输层仍有彻底解决(每流独立)

核心收益:

  • 弱网(高丢包、高延迟)下表现明显更好;
  • 连接迁移:手机从 WiFi 切 4G 不用重连;
  • 握手更快。

五、Nginx 开启 HTTP/3

需要 Nginx 1.25+ 且编译时带 quic 模块(官方包一般有):

bash
nginx -V 2>&1 | grep -o "http_v3"
nginx
server {
    listen 443 ssl;
    listen 443 quic reuseport;      # UDP 443
    http2 on;

    server_name www.bzii.cn;
    ssl_certificate     /etc/letsencrypt/live/www.bzii.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.bzii.cn/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;

    # 告诉浏览器「我支持 h3」
    add_header Alt-Svc 'h3=":443"; ma=86400' always;
}

关键:UDP 443 端口必须放行。 这是最容易忘的一步:

bash
sudo ufw allow 443/udp
sudo ufw status | grep 443

# 云服务器的安全组也要放行 UDP 443!

六、验证是否生效

bash
# 看响应头(h2)
curl -I --http2 https://www.bzii.cn
# HTTP/2 200

# 看 h3
curl -I --http3 https://www.bzii.cn
# HTTP/3 200

# 看 Alt-Svc 头
curl -sI https://www.bzii.cn | grep -i alt-svc

# 详细的协议协商信息
curl -v --http2 https://www.bzii.cn 2>&1 | grep -i "ALPN"

浏览器里:DevTools → Network → 右键表头 → 勾选「Protocol」,能看到每个请求用的 h2h3

bash
# 测试 UDP 443 是否可达(从另一台机器)
nc -zuv your-server-ip 443

在线工具:HTTP/3 Check

七、Cloudflare 用户更简单

如果用 Cloudflare CDN:

  • HTTP/2:默认开启;
  • HTTP/3:在 Network 设置里一键开启(免费版就有);
  • 源站不需要做任何改动(CF 与用户之间用 h3,CF 与源站之间仍可用 h2 或 http/1.1)。

这是用 CDN 的一个隐藏好处:新协议的支持由 CDN 负责,你的 Nginx 什么都不用改。

八、实践建议的变化

HTTP/2 之后,一些老的优化建议要反过来:

老做法HTTP/2 下
合并多个 JS/CSS拆开更好(细粒度缓存)
域名分片不要做(多一个连接和 TLS 握手)
图片内联 base64不划算,还会增大 HTML
减少请求数优先级降低,但不等于完全不重要

仍然有效的:

  • 压缩(gzip/brotli);
  • 缓存策略;
  • 减少传输体积;
  • 关键资源优先加载。

九、要不要上 HTTP/3

情况建议
用 Cloudflare直接开,零成本
自建 + Nginx 1.25+可以开,注意 UDP 443
用户主要在国内收益一般(网络质量本身较好),但也无副作用
老版本 Nginx先升到 HTTP/2

我的做法:源站开 HTTP/2,Cloudflare 侧开 HTTP/3。能白拿的收益就拿,不为了 h3 大动干戈。

另外提醒:HTTP/3 走 UDP,部分企业网络会屏蔽 UDP 443。所以必须保留 TCP 回退——Alt-Svc 机制就是干这个的,浏览器发现 h3 不通会自动回退到 h2。