计算机网络学习站

kp-025 · 05-应用层与Web

HTTP/2 与 HTTP/3(QUIC)

前沿 约 25 分钟 HTTP/2HTTP/3QUIC多路复用
我的进度:

注:本文基于模型知识整理,建议结合权威教材与 RFC 原文核对细节。

一句话定义

HTTP/2 用二进制分帧与单连接多路复用消除了应用层队头阻塞,HTTP/3 把传输层换成基于 UDP 的 QUIC(Quick UDP Internet Connections),连 TCP 造成的传输层队头阻塞也一并解决。

为什么重要

一个现代页面动辄几十上百个资源请求,HTTP/1.1 的连接排队是首屏延迟的主要来源之一。HTTP/2 已是默认配置,HTTP/3 在 CDN 与大型站点成熟落地。调优站点性能、选型网关协议、读懂浏览器 DevTools 里的 h2/h3 标记,都必须知道这两代协议分别解决了什么、又留下了什么。

前置知识

建议先读 kp-023《HTTP》,重点掌握持久连接与队头阻塞的成因;再读 kp-018《TCP 连接管理》,理解 TCP 单一有序字节流的语义——这是「为什么 HTTP/2 仍会卡」的关键;QUIC 建立在 UDP 之上,还需知道 UDP 无连接、不保证可靠的基本特性。

核心概念

  • 1.1 的性能痛点:keep-alive 连接上同一时刻只能有一个未完成响应,其余请求排队(响应队头阻塞);并发只能靠浏览器对同一域名开多条连接(经典上限 6 条),连接数、握手与慢启动开销都被放大。
  • HTTP/2 的核心改动:二进制分帧层——报文被拆成更小的帧(frame),解析不再依赖文本;单连接多路复用——一条 TCP 连接上并行多个流(stream),每个流承载一对请求/响应,帧交错发送、按流 ID 重组,流之间应用层互不阻塞;HPACK 头部压缩——静态表加动态表加哈夫曼编码,重复头部只传索引;流优先级——声明依赖与权重,服务器据此调度帧的发送顺序。
  • HTTP/2 没解决的根本问题:它仍跑在单条 TCP 上,TCP 只提供一个全局有序字节流,任何一段丢包都要等重传补齐才能交付后续数据——所有流一起被卡住,即传输层队头阻塞;高丢包环境下 HTTP/2 单连接甚至可能劣于 1.1 的多条连接。
  • QUIC 的针对性设计:基于 UDP 在用户态重建可靠传输,协议演进随应用发布、不依赖操作系统内核升级;每个流拥有独立的包编号与确认空间,一个流丢包只重传该流,彻底消除传输层队头阻塞;握手内嵌 TLS 1.3,首次连接 1-RTT、会话恢复 0-RTT 即可发数据;连接以 Connection ID 标识而非四元组,网络切换(Wi-Fi 切 4G)导致 IP 变化后连接继续,即连接迁移。

图示

三代协议在队头阻塞上的差异:

HTTP/1.1:单连接串行(应用层队头阻塞)
  请求1 ──▶ 等响应1 ──▶ 请求2 ──▶ 等响应2 ──▶ 请求3(继续排队)

HTTP/2:单条 TCP 连接,多流交错传帧(应用层并行)
  连接内: [s1帧][s2帧][s3帧][s1帧][s2帧]   按流 ID 重组各自报文
  隐患:   任一 TCP 段丢包,TCP 停等重传,所有流的帧一起被卡住
          (传输层队头阻塞)

HTTP/3(QUIC):每个流独立的包空间
  stream1 丢包 → 只重传且只阻塞 stream1 的交付
  stream2 / stream3 的数据照常确认、照常上交应用层

原理与机制

分帧如何支撑复用。 每个帧带有流 ID、类型与长度;发送端把不同流的帧交叉写入同一条 TCP 连接,接收端按流 ID 分别缓存重组。于是慢响应不再霸占整条连接,只表现为它自己那条流的帧到得慢——应用层的排队被取消。

QUIC 为什么建在 UDP 上。 新传输层协议难以穿越中间网络,而 UDP 几乎处处可通行;把可靠性、有序性与拥塞控制移到用户态实现,算法可以随应用升级、可插拔替换(与 kp-020《流量与拥塞控制》中的算法族衔接,QUIC 默认集成类似 CUBIC/BBR 的用户态实现)。HTTP/3 即 HTTP 语义(方法、状态码、首部,头部压缩改用 QPACK)跑在 QUIC 之上,对应用开发者而言接口语义不变。

部署现状。 主流大站与 CDN 已默认启用 HTTP/2,HTTP/3 支持成熟:浏览器与服务端实现齐备,站点多通过 Alt-Svc 响应头或 DNS 的 HTTPS 记录引导客户端升级到 QUIC。

实例分析

打开浏览器 DevTools 的 Network 面板,查看 Protocol 列:同站资源标 h2 说明走了 HTTP/2,标 h3 说明走了 QUIC;用 curl --http2 与 curl --http3 对同一 URL 分别请求,可对比建连与响应耗时。移动端弱网下差异最明显:QUIC 的连接迁移让 Wi-Fi 与蜂窝切换不重连,流间隔离让个别丢包不再拖累整页资源。

常见误区

  • HTTP/2 不是普遍更快:低并发、低丢包时收益有限;高丢包时传输层队头阻塞甚至让它劣于 1.1 的多连接方案。
  • 多路复用不等于「请求越多越好」:请求数仍需控制,改变的只是排队方式与连接开销。
  • HTTP/3 仍有握手:QUIC 内嵌 TLS 1.3,首次 1-RTT;0-RTT 仅限会话恢复且只能承载幂等请求。
  • 队头阻塞有两层:应用层(1.1)与传输层(2 over TCP);HTTP/2 只解决了前者,两层都要消除才是 HTTP/3。

自测题

  1. HTTP/1.1 的队头阻塞发生在哪一层?HTTP/2 如何解决,又暴露了什么新问题?

答案要点: 1.1 的阻塞在应用层:一条连接同一时刻只能等一个响应,请求必须排队。HTTP/2 用二进制分帧加单连接多流交错传输,应用层流间不再阻塞;但底层仍是单条 TCP 全局有序字节流,任一段丢包会让所有流等待重传,即传输层队头阻塞。

  1. QUIC 为什么选择建在 UDP 上?

答案要点: UDP 几乎处处可通行,新传输层协议难以穿越中间网络;把可靠传输、有序性与拥塞控制移到用户态后,协议演进随应用发布、不依赖内核升级,算法也可插拔。

  1. QUIC 如何实现连接迁移?

答案要点: 用 Connection ID 标识连接,而非(源IP:端口、目的IP:端口)四元组;网络切换导致 IP 变化时,凭 Connection ID 在新路径上继续确认与传输,连接不断线。

  1. HPACK 压缩头部用了哪三种手段?

答案要点: 静态表(常见头键值对固定索引)、动态表(连接内缓存出现过的头部供后续引用索引)、哈夫曼编码(压缩字符串取值)。

  1. HTTP/3 的 0-RTT 建连适合承载什么请求?

答案要点: 仅限会话恢复且幂等的请求(如 GET),因为 0-RTT 早期数据没有防重放保护,可能被攻击者原样重发,非幂等操作必须等 1-RTT 握手完成后再发。

延伸阅读

  • 《High Performance Browser Networking》(Ilya Grigorik)
  • RFC 9113(HTTP/2)、RFC 9000(QUIC 传输协议)、RFC 9114(HTTP/3)