Files
2026-05-24 11:42:38 +08:00

6.4 KiB
Raw Permalink Blame History

tags, create time
tags create time
计算机网络
HTTP/3
QUIC
TLS 1.3
2026-05-18 02:50

HTTP/3 与 QUIC

概述

HTTP/3 (RFC 9114) 基于 QUIC 协议,将传输层从 TCP 替换为 UDP + 内嵌的可靠传输机制。核心目标:消除 TCP 层的 Head-of-Line blocking,实现更快的连接建立和多路复用。

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 连接生命周期

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
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

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 ✅

关联笔记