第 15 章:HTTP/3 与 QUIC
第 15 章:HTTP/3 与 QUIC
HTTP/3 是 HTTP 协议的最新版本,基于 QUIC 传输协议(基于 UDP),解决了 HTTP/2 遗留的 TCP 队头阻塞问题。
15.1 HTTP/3 概述
协议栈对比
HTTP/1.1: HTTP ──────────── TCP ─── TLS ─── IP
HTTP/2: HTTP/2 ─────────── TCP ─── TLS ─── IP
HTTP/3: HTTP/3 ─── QUIC(UDP) ──── TLS 1.3 ─── IP
| 版本 | 传输层 | 加密 | 连接建立 |
|---|
| HTTP/1.1 | TCP | 可选 TLS | 1-3 RTT |
| HTTP/2 | TCP | 推荐 TLS | 1-3 RTT |
| HTTP/3 | QUIC (UDP) | 内置 TLS 1.3 | 0-1 RTT |
15.2 QUIC 协议
QUIC 是什么
QUIC(Quick UDP Internet Connections)是 Google 开发的基于 UDP 的传输协议,已成为 IETF 标准。
QUIC 核心特性
| 特性 | 说明 |
|---|
| 基于 UDP | 避免操作系统 TCP 栈的限制 |
| 内置 TLS 1.3 | 安全性开箱即用 |
| 多路复用 | 消除 TCP 层队头阻塞 |
| 连接迁移 | 网络切换不断线 |
| 0-RTT | 首次连接后可零延迟建立 |
15.3 消除队头阻塞
HTTP/2 的问题
HTTP/2 多路复用在 TCP 上:
流1: [数据]────────────────────→
流2: [数据]──→ [丢包!] ────────→ [重传等待]
流3: [数据]──────────→ [被阻塞!]
流4: [数据]──────────→ [被阻塞!]
TCP 层的丢包会阻塞所有流
HTTP/3 的解决方案
HTTP/3 在 QUIC 上:
流1: [数据]────────────────────→
流2: [数据]──→ [丢包!] ────────→ [仅流2受影响]
流3: [数据]────────────────────→ (不受影响)
流4: [数据]────────────────────→ (不受影响)
QUIC 在传输层独立处理每个流
15.4 连接迁移
TCP 的问题
WiFi 连接: TCP 连接 = {源IP: 192.168.1.100, 源端口: 54321, ...}
切换到 4G: TCP 连接 = {源IP: 10.0.0.50, 源端口: 54321, ...}
IP 变化 → TCP 连接断开 → 需要重新建立连接
QUIC 的解决方案
QUIC 使用 Connection ID 而非 IP:Port 标识连接
WiFi: Connection ID = "abc123" → IP: 192.168.1.100
4G: Connection ID = "abc123" → IP: 10.0.0.50
连接 ID 不变 → 连接不中断
15.5 0-RTT 连接建立
传统 TLS 连接(2-3 RTT)
客户端 服务器
│ │
│── ClientHello ─────────→│ ┐
│←── ServerHello + Cert ──│ │ 1 RTT (TLS)
│── Finished ─────────────│ ┘
│ │
│── 首个请求 ─────────────→│ ┐
│←── 响应 ────────────────│ │ 1 RTT (应用)
│ │ ┘
首次连接: 2-3 RTT
QUIC 0-RTT
首次连接 (1-RTT):
客户端 服务器
│ │
│── Initial + Crypto ────→│ ┐
│←── Handshake ───────────│ │ 1 RTT
│── Finished + 请求 ─────→│ ┘
后续连接 (0-RTT):
客户端 服务器
│ │
│── Initial + 0-RTT 数据 ─→│ 直接发送请求
│←── 响应 ────────────────│ 无需等待握手
15.6 HTTP/3 帧与流
HTTP/3 帧类型
| 帧类型 | 值 | 说明 |
|---|
| DATA | 0x0 | 数据帧 |
| HEADERS | 0x1 | 头部帧 |
| CANCEL_PUSH | 0x3 | 取消推送 |
| SETTINGS | 0x4 | 设置帧 |
| PUSH_PROMISE | 0x5 | 推送承诺 |
| GOAWAY | 0x7 | 关闭连接 |
| MAX_PUSH_ID | 0xD | 最大推送 ID |
头部压缩:QPACK
HTTP/3 使用 QPACK 替代 HPACK,解决了 HPACK 在乱序流中的问题。
| 特性 | HPACK (HTTP/2) | QPACK (HTTP/3) |
|---|
| 依赖顺序 | 严格有序 | 允许乱序 |
| 阻塞 | 可能阻塞 | 单向流更新 |
| 动态表 | 主连接 | 独立编码器流 |
15.7 浏览器支持与启用
检测 HTTP/3 �持
// 检查浏览器是否支持 HTTP/3
if (window.chrome) {
console.log('Chrome 支持 HTTP/3');
}
// 使用 curl 测试
// curl --http3 https://www.example.com
Nginx HTTP/3 配置
# Nginx 1.25.0+ 支持 HTTP/3
server {
listen 443 quic reuseport; # HTTP/3
listen 443 ssl; # HTTP/2 (降级)
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# HTTP/3 头部
add_header Alt-Svc 'h3=":443"; ma=86400';
location / {
root /var/www/html;
}
}
# 测试 HTTP/3
curl --http3 https://example.com
# 查看协议版本
curl --http3 -v https://example.com 2>&1 | grep "ALPN"
15.8 HTTP/2 vs HTTP/3
| 特性 | HTTP/2 | HTTP/3 |
|---|
| 传输层 | TCP | QUIC (UDP) |
| 队头阻塞 | TCP 层仍有 | 完全消除 |
| 握手延迟 | 1-3 RTT | 0-1 RTT |
| 连接迁移 | 不支持 | 支持 |
| 头部压缩 | HPACK | QPACK |
| 加密 | 可选 TLS | 强制 TLS 1.3 |
| 操作系统支持 | 内核 TCP | 用户空间实现 |
15.9 业务场景:CDN HTTP/3 配置
# Cloudflare-style HTTP/3 配置
server {
# HTTP/3 (QUIC)
listen 443 quic reuseport;
# HTTP/2 (降级方案)
listen 443 ssl http2;
server_name cdn.example.com;
ssl_certificate /etc/ssl/certs/cdn.pem;
ssl_certificate_key /etc/ssl/private/cdn.key;
ssl_protocols TLSv1.3; # HTTP/3 需要 TLS 1.3
# 告知客户端支持 HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';
# 静态资源
location /static/ {
alias /var/www/static/;
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
⚠️ 注意事项
- UDP 防火墙:确保防火墙允许 UDP 443 端口
- 降级支持:必须同时支持 HTTP/2 或 HTTP/1.1 降级
- 负载均衡:QUIC 使用 Connection ID,需要支持的负载均衡器
- 0-RTT 重放攻击:0-RTT 数据可能被重放,重要操作应验证
- 监控:HTTP/3 需要新的监控指标和工具
🔗 扩展阅读
下一章:第 16 章:HTTP 安全 — TLS、HSTS、CSP、证书管理、中间人攻击防护