本页目录

HTTP/3

HTTP/3 在 QUIC 上跑 HTTP——不再依赖 TCP,用 UDP 封装,stream 之间完全独立(无队头阻塞)。QPACK 替代 HPACK,0-RTT 恢复连接。HTTP 语义没变,传输层彻底重写。

概述

HTTP/3(RFC 9114, 2022)将 HTTP 从 TCP 迁移到 QUIC(UDP),解决了 HTTP/2 最大的遗留问题——TCP 层队头阻塞。一个 stream 的丢包不再阻塞其他 stream。QUIC 的连接迁移还使移动网络切换(WiFi↔4G)不再断开 HTTP 连接。QPACK 替代 HPACK 解决了 header 压缩的动态表 HOL 阻塞。HTTP/3 使用了与 HTTP/2 完全相同的语义——只是换了传输层。

HTTP/3 = HTTP/2 semantics + QUIC transport

HTTP/3 保留了 HTTP/2 的全部语义 (streams, multiplexing, headers, methods, status codes) 但换掉了传输层: TCP → QUIC (UDP)。

主要变化:

  • Stream: 不再是 TCP byte stream 上的 frame multiplexing → QUIC 的 stream 是协议首层
  • HPACK → QPACK: 解决 HPACK 的"动态表更新丢失 → HOL blocking"
  • TLS 1.3: 强制 (QUIC 内建加密, 无明文的 HTTP/3)
  • Server Push: 已废弃 (Chrome/nginx 均已移除)

QPACK

HPACK 的问题: 如果包含动态表更新的 HEADERS frame 丢了 → 接收方无法解码后续 HEADERS → HOL blocking again!

QPACK: 动态表更新和数据帧在 QUIC 的不同 unidirectional streams 上传输:

  Encoder Stream (单向, QPACK encoder → decoder):
    表更新: Insert (name, value) + TSS (Table State Synchronize)
  
  Decoder Stream (单向, decoder → encoder):
    Feedback: Section Acknowledgment, Stream Cancellation

  请求/响应流 (bidi):
    HEADERS + DATA frames (引用动态表 index)

  → 表更新的丢包只阻塞 Encoder Stream (表更新), 不阻塞请求/响应!

部署: Alt-Svc

HTTP/2 or HTTP/1.1 response header:
  Alt-Svc: h3=":443"; ma=86400

  h3: HTTP/3 over QUIC
  ma (max-age): 86400 秒内记住此 alternative
  :443: QUIC 端口 (通常相同端口)

  Browser: 收到 Alt-Svc → 下次连接到同一 host → 优先尝试 QUIC:443
          → 如果 QUIC 不通 (UDP blocked, QUIC version mismatch) → fallback to TCP

参考

  • RFC: 9114, 9204
  • 工具⁠: curl --http3 -v, Chrome chrome://net-internals/#http3

Keywords: HTTP/3, QUIC, QPACK, Alt-Svc, connection migration, 0-RTT, unidirectional streams