这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 HTTP/3 将 HTTP 的传输基础从 TCP 切换到 QUIC。QUIC 基于 UDP,在用户态实现可靠传输、流多路复用、内置 TLS 1.3、连接迁移和更快的握手恢复。它解决 TCP 时代难以演进的问题,也带来 UDP 防火墙、负载均衡和内核生态的新挑战。
17.1 TCP 的演进瓶颈
TCP 部署在操作系统内核和大量中间设备中,修改成本高:
- 拥塞算法迭代依赖内核版本;
- TCP 队头阻塞难以在 HTTP 层解决;
- 连接四元组变化即连接身份变化;
- TLS 与 TCP 分层,握手难以进一步合并;
- 中间设备可能干扰扩展选项。
QUIC 选择 UDP 作为底层承载,把传输层能力放到用户态应用和库中,便于迭代。
17.2 QUIC 基本特性
| 特性 | 价值 |
|---|---|
| 集成 TLS 1.3 | 传输与加密握手协同 |
| 流独立性 | 一个流丢包不阻塞其他流 |
| 连接 ID | 地址变化后仍可识别连接 |
| 0-RTT | 恢复连接降低延迟 |
| 用户态实现 | 迭代快,可随应用发布 |
| 拥塞控制可插拔 | 便于部署现代算法 |
17.3 队头阻塞的改善
HTTP/2 多路复用后,多个流共享一条 TCP 字节流:
Stream 1 / Stream 2 / Stream 3
\ | /
TCP byte stream
|
丢包阻塞所有流
QUIC 为不同流维护独立交付状态:
Stream 1 丢包
-> Stream 2 已完整到达的数据可以交付
它消除传输层流之间的队头阻塞,但单个流内部仍是有序字节流,应用处理慢也会造成该流阻塞。
17.4 连接迁移
TCP 连接通常由四元组标识:
Source IP + Source Port + Destination IP + Destination Port
网络从 Wi-Fi 切到 5G 后,源地址变化,旧 TCP 连接无法继续。
QUIC 使用 Connection ID:
地址变化
-> Connection ID 不变
-> 连接可以迁移
-> 应用会话不必须重建
迁移仍需路径验证、安全策略和负载均衡支持。Connection ID 也可能被用于用户跟踪,需要编码和轮换治理。
17.5 握手与 0-RTT
QUIC 集成 TLS 1.3:
Client -> Initial + CRYPTO
Server -> Initial + Handshake + CRYPTO
Client -> Finished
与 TCP + TLS 相比,可减少一次 RTT。恢复连接时可使用 0-RTT 提前发送应用数据。
0-RTT 风险:
- 可能重放;
- 不能直接用于非幂等写操作;
- 早期数据加密强度有限;
- 服务端需要防重放策略。
常见做法是 0-RTT 只用于幂等 GET 或携带一次性令牌的握手。
17.6 QUIC 流与控制
QUIC 有连接级和流级控制:
| 类型 | 说明 |
|---|---|
| 双向流 | 两侧都可发送 |
| 单向流 | 只有一个方向发送 |
| MAX_DATA | 连接级窗口 |
| MAX_STREAM_DATA | 流级窗口 |
| CRYPTO | 加密握手数据 |
| ACK | 确认 |
| CONNECTION_CLOSE | 关闭 |
帧格式和细节由 QUIC 标准定义,应用开发通常通过库和运行时使用,不需要手工解析。
17.7 拥塞控制
QUIC 的 ACK 机制携带更丰富的传输时延信息,便于估算 RTT 和丢包。常见实现支持:
- CUBIC;
- BBR;
- 自定义实验算法。
由于 QUIC 在用户态运行,应用可以更快获得新算法,但 CPU 成本和库实现质量必须评估。
17.8 部署要求
启用 HTTP/3 需要:
- 服务端支持 QUIC/HTTP/3;
- UDP 443 可达;
- 证书与 TLS 1.3 配置正确;
- Alt-Svc 告知客户端;
- 客户端支持;
- LB 或 Ingress 支持;
- 防火墙放行 UDP;
- 监控 QUIC 流量。
Alt-Svc 示例:
Alt-Svc: h3=":443"; ma=86400
Nginx 新版本可能支持 HTTP/3,但指令和稳定性取决于版本,应查阅当前版本文档。
17.9 排障
查看协议:
curl -I --http3 https://www.example.com
抓包:
tcpdump -i eth0 udp port 443 -w quic.pcap
Wireshark 可解析 QUIC,但密钥导出配置会影响解密效果。服务端应记录:
- QUIC 版本;
- 握手成功率和失败原因;
- 0-RTT 比例;
- 连接迁移次数;
- RTT 和丢包;
- 流数量;
- UDP 缓冲丢弃;
- CPU 使用率。
常见问题:
| 现象 | 原因 |
|---|---|
| HTTP/3 无法建立 | UDP 被防火墙拦截 |
| 回退 HTTP/2 | 客户端或 Alt-Svc 不支持 |
| 握手失败 | 证书、版本、SNI 配置 |
| 吞吐低 | UDP 缓冲、丢包、算法 |
| CPU 高 | 用户态协议栈成本 |
| LB 异常 | 不支持连接 ID 路由 |
17.10 适用判断
适合:
- 弱网和移动网络用户;
- 高 RTT 跨地域访问;
- 大量并发小请求;
- 需要连接迁移;
- CDN 和边缘接入。
需评估:
- 服务端 CPU;
- 运维观测能力;
- 中间网络对 UDP 的策略;
- 客户端兼容;
- 是否已有 HTTP/2 长连接优化;
- LB 和代理支持程度。
本章小结
HTTP/3 基于 QUIC,在 UDP 上实现可靠传输、流独立交付、TLS 1.3、连接迁移和快速恢复。它改善 TCP 队头阻塞、握手延迟和网络切换体验,但部署依赖 UDP 443、客户端支持和基础设施能力。是否启用应基于用户网络形态、CPU 成本和可观测性验证。
思考题
- QUIC 为什么能减少 HTTP/2 的 TCP 队头阻塞?
- Connection ID 如何支持连接迁移?
- 0-RTT 有什么安全风险?
- HTTP/3 部署需要哪些网络条件?
- 设计一次 HTTP/3 灰度验证方案。