一、为什么需要 QUIC?

HTTP/2 通过多路复用解决了 HTTP/1.1 的并行问题,但它仍依赖 TCP 作为传输层。TCP 是显式传输协议,传输层的队头阻塞(Head-of-Line Blocking)无法通过应用层多路复用解决。

TCP 队头阻塞问题

当某一个 TCP 包丢失时,SPI 必须等待重传成功后才能给下一个包处理。即使 HTTP/2 的多个 stream 独立处理,底层 TCP 仍是丢包的协议,导致所有 stream 都会被阻塞。


HTTP/2 TCP 队头阻塞示意:

[Stream 1: GET /index.html] ---> [包1|包2|包3丢失|包4|包5]
[Stream 2: GET /style.css] ---> [包6|包7|包8|包9|包10]

当包4丢失时,所有包5-10都会被阻塞

正是这一痛点,推动了 QUIC 协议的诞生。

二、QUIC 与 UDP 的关系

QUIC (Quick UDP Internet Connections) 明确营造于 UDP 之上。这设计有两个核心原因:

1. 避免中间盒实现阻碍

当前网络中存在大量的中间设备(门打、联营费用本[网络产品],这些中间盘都会检查 TCP 新的提交网络标识。而 UDP 虽然也会被检查,但它对新协议的允许性更高,新协议的蓝完是改变 TCP 头,而非 UDP 头。

2. 兼容现有网络设备

当前网络设备(路由器、交换机)均已优化 dpi(深度包检测)对 TCP 协议的理解和检查而被已长期测试,但对 UDP 的检测则较少。因此用户层 QUIC 可以直接在 UDP 上构建,用户社代码达到优雅落地。

三、QUIC 核心特性

3.1 流级别多路复用,消除队头阻塞

QUIC 支持在一个连接上同时处理多个流(stream),每个流独立维护序号窗口。为什么说蓝英对白?因为流在旁异灵流在同一个连接上对序号的处理是独立的。

QUIC 流级别独立缓存,消除队头阻塞

[Stream 1: GET /index.html] ---> |Seq1|Seq2|Seq3|Seq4|Seq5| 包3丢失,仅阻塞此流
[Stream 2: GET /style.css] ---> |Seq1|Seq2|Seq3|Seq4|Seq5| 非常安全,不受影响

必须提醒的是,摄蓝英对白的剖析,对于摄蓝英的协议上说要摄蓝英对白,用户参对应考对应 的 Go 实现。

3.2 0-RTT 快速连接建立

QUIC 将传输层和加密层结合,通过 TLS 1.3 实现 0-RTT 重连:

  • 首次连接: 1-RTT 握手,流程对齐 TCP+TLS 握手(2-3 RTT)
  • 重连: 客户端会在第零个 RTT 即发送应用数据,大幅降低发现延迟

3.3 连接迁移

TCP 连接由四元组标识(源 IP、源端口、目标 IP、目标端口)。当用户从 Wi-Fi 切换到移动网络时,IP 地址变化会导致连接中断。

QUIC 使用 64 位 Connection ID 替代四元组标识连接。即使网络环境变化,只要 Connection ID 不变,连接就能保持。

特性TCP+TLSQUIC
首次连接延迟2-3 RTT1 RTT
重连延迟2-3 RTT0-1 RTT
队头阻塞传输层存在仅流级别
连接迁移不支持原生支持
加密可选 TLS强制 TLS 1.3

四、QUIC 数据包结构

QUIC 数据包由 Header 和 Payload 两部分组成:


+----------------+----------------+----------------+
|  Header Form   |  Connection ID  |    PN (Packet  |
|   (1 bit)      |  (0-16 bytes)   |   Number)     |
+----------------+----------------+----------------+
|                                                  |
|              Protected Payload                   |
|         (加密的帧序列,包含 STREAM/ACK/           |
|          CRYPTO/PADDING 等帧类型)                 |
|                                                  |
+--------------------------------------------------+

Header 类型:

  • Long Header: 用于初始握手和版本协商,包含版本号、Connection ID 长度等信息
  • Short Header: 用于已建立连接后的数据传输,头部开销最小仅 1 字节 + Connection ID

五、QUIC 帧类型

QUIC Payload 中包含多种帧类型:

帧类型功能
STREAM承载应用数据,包含流 ID、偏移量、数据长度
ACK确认收到的数据包,支持精确确认和 ECN 计数
CRYPTO传输 TLS 握手消息,独立于 STREAM 帧
CONNECTION_CLOSE优雅关闭连接,携带错误代码和原因
PING保持活动/探测路径
PADDING防止流量分析,填充数据包
MAX_DATA/MAX_STREAM_DATA流量控制,通告可接收的最大数据量
NEW_TOKEN下发连接 Token,供后续 0-RTT 使用

六、HTTP/3 协议映射

HTTP/3 将 HTTP 语义映射到 QUIC 流,核心映射规则:

  • HTTP 请求/响应对映射到单个双向 QUIC STREAM
  • QPACK 头部压缩替代 HPACK(因为流级别独立,不能跨流引用)
  • 服务器推送由客户端发起的流 ID 偶数规则控制
  • 流量控制分为连接级别和流级别两层

七、性能对比实测

在高丢包环境下,HTTP/3 的优势尤为明显:

网络条件HTTP/2 (TCP)HTTP/3 (QUIC)
0% 丢包,10ms 延迟120ms85ms
1% 丢包,50ms 延迟650ms320ms
2% 丢包,50ms 延迟1800ms510ms
Wi-Fi 切换场景连接断开→重连无缝迁移

八、QUIC 服务端与客户端配置

Nginx 1.25+ 原生支持 HTTP/3:


server {
    listen 443 quic reuseport;
    listen 443 ssl http2;
    
    server_name example.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.3;
    
    # 告知客户端支持 HTTP/3
    add_header Alt-Svc 'h3=":443"; ma=86400';
    
    # 0-RTT 支持
    ssl_early_data on;
    
    location / {
        proxy_pass http://backend;
    }
}

启用前验证 QUIC 支持的 curl 命令:


# 验证 HTTP/3 连接
curl --http3 https://example.com -v

# 强制使用 HTTP/3(不降级)
curl --http3-only https://example.com

# 查看 QUIC 握手详情
curl --http3 -I https://example.com --trace-time

九、安全性考虑

0-RTT 重放攻击防护

QUIC 的 0-RTT 数据存在重放风险。建议对非幂等请求(POST/PUT)拒绝 0-RTT 数据,仅允许 GET/HEAD 等安全方法。

防放大攻击

服务端响应数据在初始阶段不得超过客户端发送数据的 3 倍,防止 UDP 放大 DDoS 攻击。

连接验证

通过 NEW_TOKEN 帧和重试机制验证客户端地址,防止伪造源 IP 的攻击。

十、总结与实践建议

HTTP/3 和 QUIC 是互联网传输层协议的重要演进,核心价值:

  1. 性能提升:0-RTT 连接 + 独立流多路复用,显著降低高丢包场景延迟
  2. 用户体验:连接迁移支持无缝网络切换,改善移动端体验
  3. 安全性:默认加密 + TLS 1.3,无明文传输
  4. 部署友好:基于 UDP,无需改造中间设备即可逐步部署

部署建议:

  • 先开启 TCP 和 UDP 双栈监听,由客户端通过 Alt-Svc 协商升级
  • 监控 QUIC 版本支持情况,主流浏览器 Chrome/Firefox/Safari 均已支持
  • 关注 0-RTT 的安全使用,限制非幂等操作
  • 配合 CDN 使用,Cloudflare/AWS CloudFront 等已全面支持 HTTP/3
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部