Skip to content

HTTP/3 与 QUIC 协议

1. 为什么需要 QUIC?

HTTP/2 over TCP 的问题

  1. TCP 队头阻塞: 一个包丢失,所有 Stream 阻塞等待重传
  2. 握手延迟: TCP 3-RTT + TLS 1-2 RTT = 连接建立慢
  3. 连接迁移困难: IP 变化 (WIFI → 4G) 需重新握手

QUIC 的解决方案

  • 基于 UDP: 用户空间实现可靠传输,绕过内核 TCP 栈
  • Stream 独立: 一个 Stream 丢包不影响其他 Stream
  • 0-RTT / 1-RTT 握手: 内置 TLS 1.3
  • Connection ID: 连接与 IP 解耦

2. QUIC 核心特性

2.1 多路复用无队头阻塞

HTTP/2 over TCP:
  Stream 1 ─┬─ Packet Lost ─┬─> ALL BLOCKED
  Stream 2 ─┘               │
  Stream 3 ─────────────────┘

QUIC:
  Stream 1 ─── Packet Lost ──> Only Stream 1 blocked
  Stream 2 ─────────────────> OK
  Stream 3 ─────────────────> OK

2.2 0-RTT 握手

传统 TCP + TLS:
  Client                    Server
    |------- SYN ------->|       (1 RTT)
    |<----- SYN+ACK -----|
    |------- ACK ------->|
    |--- ClientHello --->|       (2 RTT)
    |<-- ServerHello ----|
    |---- Finished ----->|       (3 RTT)
    |<---- Data ---------|

QUIC 0-RTT (恢复连接):
  Client                    Server
    |-- ClientHello + Data -->|  (0 RTT for data!)
    |<-- ServerHello + Data --|

实现原理: 客户端缓存 Session Ticket,下次连接直接发送加密数据。

2.3 Connection ID

  • 连接由 Connection ID 标识,而非 (IP, Port) 四元组
  • 网络切换 (WIFI → 4G) 时,Connection ID 不变,连接不中断
  • 对移动端 App 极为重要

2.4 拥塞控制

  • 默认使用 Cubic (与 TCP 类似)
  • 支持 BBR (Google 开发,基于带宽估计)
  • 可插拔设计,易于升级

3. HTTP/3 协议栈

+---------------------+
|       HTTP/3        |  (语义与 HTTP/2 相同)
+---------------------+
|        QPACK        |  (类似 HPACK,但无序)
+---------------------+
|        QUIC         |  (传输层,含加密)
+---------------------+
|        UDP          |
+---------------------+
|        IP           |
+---------------------+

QPACK vs HPACK

  • HPACK 依赖有序传输 (动态表需同步)
  • QPACK 允许乱序,适应 QUIC 的无序 Stream

4. 前端如何感知 HTTP/3?

检测协议版本

javascript
// Performance API
const entries = performance.getEntriesByType('navigation');
console.log(entries[0].nextHopProtocol); // "h3" / "h2" / "http/1.1"

// 或资源
const resources = performance.getEntriesByType('resource');
resources.forEach(r => console.log(r.name, r.nextHopProtocol));

Alt-Svc 升级机制

服务端通过 Alt-Svc 响应头告知客户端支持 HTTP/3:

http
Alt-Svc: h3=":443"; ma=86400

浏览器后续请求自动尝试 QUIC。


5. 部署现状 (2024)

  • Cloudflare, Google, Meta 已全面支持
  • Nginx 1.25+ 支持 (需编译 quiche/boringssl)
  • Node.js 实验性支持 (--experimental-quic)

前端面试知识库