176 lines
6.4 KiB
Markdown
176 lines
6.4 KiB
Markdown
---
|
||
tags: [计算机网络, HTTP/3, QUIC, TLS 1.3]
|
||
create time: 2026-05-18 02:50
|
||
---
|
||
|
||
# HTTP/3 与 QUIC
|
||
|
||
## 概述
|
||
|
||
HTTP/3 (RFC 9114) 基于 **QUIC** 协议,将传输层从 TCP 替换为 UDP + 内嵌的可靠传输机制。核心目标:**消除 TCP 层的 Head-of-Line blocking**,实现更快的连接建立和多路复用。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["HTTP/3 over QUIC<br/>UDP 443"] -->|"零 RTT 建连"| B["更快 ✅"]
|
||
C["HTTP/2 over TCP<br/>TCP 443"] -->|"三次握手 + TLS"| D["较慢"]
|
||
|
||
style A fill:#98FB98,color:#000
|
||
style C fill:#FFD700,color:#000
|
||
```
|
||
|
||
## QUIC 协议栈对比
|
||
|
||
```
|
||
HTTP/3 Stack: HTTP/2 Stack:
|
||
──────────── ────────────
|
||
HTTP/3 HTTP/2
|
||
│ │
|
||
┌─┴─────────────────┐ ┌──────┴──────────────┐
|
||
│ QUIC │ │ TLS 1.3 │
|
||
│ + Multiplexing │ │ + TCP Flow Control │
|
||
│ + Crypto │ └──────┬──────────────┘
|
||
│ + Reliable Tx │ │
|
||
└──────┬─────────────┘ ┌────┴─────┐
|
||
│ │ TCP │
|
||
▼ └────┬─────┘
|
||
UDP 443 │
|
||
▼
|
||
IP / Ethernet
|
||
```
|
||
|
||
### 关键设计哲学
|
||
|
||
```
|
||
TCP 的问题: QUIC 的方案:
|
||
───────── ──────────
|
||
• 一条流 HOL blocking • 多 Stream 独立重传
|
||
• 拥塞控制固定算法 • 应用层可调拥塞算法 (BBRv2 by default)
|
||
• TLS in TCP → 双重握手 • TLS 1.3 + 0-RTT session resumption
|
||
• NAT 中断需重建 TCP • Connection ID → NAT 变更无感知
|
||
```
|
||
|
||
## QUIC 连接生命周期
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Client
|
||
participant Server
|
||
|
||
Note over Client,Server: Phase 1: Connection Establishment (TLS Handshake embedded)
|
||
Client->>Server: Initial Packet (Client Hello + CRYPTO)
|
||
Note over Server: Parses CRYPTO from QUIC packet header
|
||
Server-->>Client: Server Hello + CRYPTO + HANDSHAKE
|
||
Note over Client: Session ticket cached for resume
|
||
Server-->>Client: NEW_CONNECTION_ID + RETIRE_CONNECTION_ID
|
||
Client-->>Server: ACK
|
||
|
||
Note over Client,Server: ← CONNECTION ESTABLISHED →
|
||
|
||
Client->>Server: 0-RTT Data (if session resumed) ⚡
|
||
Server->>Server: Validate 0-RTT anti-replay
|
||
Server-->>Client: 0-RTT Accepted / Rejected
|
||
|
||
Note over Client,Server: Phase 2: Data Transfer
|
||
loop Multiple Streams (independent retransmission)
|
||
Client->>Server: HEADERS(stream=X) + DATA(stream=X)
|
||
Server-->>Client: HEADERS(stream=X) + DATA(stream=X)
|
||
end
|
||
|
||
Note over Client,Server: Phase 3: Graceful Close
|
||
Client->>Server: FIN (last stream closed)
|
||
Server->>Client: FIN
|
||
Client->>Server: Final ACK
|
||
```
|
||
|
||
## 0-RTT(零往返时间)连接恢复
|
||
|
||
当客户端之前访问过同一服务器时,可以跳过完整握手:
|
||
|
||
```
|
||
首次连接: 后续连接:
|
||
────────── ──────────
|
||
Client → SYN → Server Client → QUIC Initial (with 0-RTT data)
|
||
SYN → Client → Server processes immediately!
|
||
ACK → Client ↓
|
||
Client → ClientHello 0-RTT data delivered before handshake finishes!
|
||
ServerHello + cert → Client
|
||
Client → encrypted application data
|
||
|
||
Total: 1-RTT (+0-RTT if resumed) Total: 0-RTT ⚡⚡⚡
|
||
```
|
||
|
||
> [!warning] 0-RTT 的安全风险
|
||
> 重放攻击 (Replay Attack): 中间人可捕获并重放 0-RTT 请求。因此 **0-RTT 只能用于幂等操作**(GET、HEAD、OPTIONS)。POST 等不安全操作不应使用 0-RTT。
|
||
|
||
## QUIC 如何消除 HoL Blocking
|
||
|
||
```
|
||
HTTP/2 over TCP: QUIC over UDP:
|
||
═════════════════ ═══════════════════
|
||
|
||
Stream 1: [Data][Lost❌][More] Stream 1: [✓ Data] [✓ More]
|
||
Stream 3: [OK OK OK OK OK] ← 全部卡住! Stream 3: [✓ OK] [✓ OK] [✓ OK]
|
||
Stream 5: [OK OK OK OK OK] Stream 5: [✓ OK] [✓ OK]
|
||
|
||
原因: TCP 是字节流 原因: 每个 Stream 独立编号
|
||
丢包导致所有后续 Stream 等待 ACK 丢失的数据只重传对应 Stream
|
||
```
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
L1["HTTP/2:<br/>一个包丢了<br/>全连阻塞"] -->|"TCP Hol-blocking"| SLOW["慢 ❌"]
|
||
L2["QUIC:<br/>单个stream丢包<br/>其他stream继续"] -->|"独立重传"| FAST["快 ✅"]
|
||
|
||
style SLOW fill:#FF6B6B,color:#fff
|
||
style FAST fill:#98FB98,color:#000
|
||
```
|
||
|
||
## Go 中启用 HTTP/3
|
||
|
||
```go
|
||
import "golang.org/x/net/http3"
|
||
|
||
// HTTP/3 服务器
|
||
go http.ListenAndServeTLS(":443", "cert.pem", "key.pem", srv) // h2c handler
|
||
|
||
// 自动降级到 HTTP/2
|
||
http3.ListenAndServeTLS(":443", "cert.pem", "key.pem", &http3.Server{
|
||
Handler: yourHandler,
|
||
})
|
||
|
||
// gRPC 也原生支持 HTTP/3
|
||
grpc.NewServer(grpc.HTTPSupport())
|
||
```
|
||
|
||
## HTTP/3 vs HTTP/2 对照表
|
||
|
||
| 特性 | HTTP/2 (over TCP) | HTTP/3 (over QUIC) |
|
||
|------|-------------------|---------------------|
|
||
| 传输层 | TCP | **UDP** |
|
||
| 端口 | 443 (h2 via ALPN) | **443** |
|
||
| 并发 | 单连接多 Stream | 同左 + UDP 级冗余 |
|
||
| 连接迁移 | ❌ 网卡切换 = 断连 | ✅ Connection ID |
|
||
| 头压缩 | HPACK | QPACK |
|
||
| 拥塞控制 | 内核态固定算法 | **用户态可插拔** |
|
||
| NAT 穿透 | 依赖 TCP | UDP 更友好 (运营商限制少) |
|
||
| 成熟度 | ✅ 广泛部署 | 🟢 快速普及 (Cloudflare/Google/Facebook) |
|
||
| Debug 难度 | tcpdump/Wireshark 成熟 | 工具链仍在完善 |
|
||
|
||
## 当前 adoption
|
||
|
||
| CDN/服务 | HTTP/3 状态 |
|
||
|---------|-----------|
|
||
| Cloudflare | ✅ 默认开启 |
|
||
| Google | ✅ 大规模部署 |
|
||
| Facebook/Meta | ✅ |
|
||
| Nginx | ✅ 1.25+ 正式支持 |
|
||
| Apache | ✅ mod_http3 |
|
||
| AWS ALB/NLB | ✅ |
|
||
| Vercel/Netlify | ✅ |
|
||
|
||
## 关联笔记
|
||
|
||
- [[hhs/NETWORK/HTTP/2多路复用]] — QUIC 继承了 HTTP/2 的多路复用思想
|
||
- [[hhs/NETWORK/TCP拥塞控制]] — QUIC 的用户态拥塞控制可自定义
|
||
- [[hhs/NETWORK/HTTPS与TLS握手]] — QUIC 内置 TLS 1.3
|