HTTP/2:单连接上的多路复用
更新时间:2026-09-17。网络协议域·应用层。它保留了 HTTP/1.1 的方法/状态码/头部语义,只换传输分帧;前因见 HTTP/1.1,遗留的 TCP 层队头阻塞由 HTTP/3/QUIC 解决。
HTTP/2(RFC 7540/9113)在不改变 HTTP 语义的前提下引入二进制分帧层(binary framing layer),让多个请求-响应在同一条 TCP 连接上并发交错传输,从根本上解决了 1.1 的应用层队头阻塞。
一、二进制分帧:连接—流—消息—帧
层级关系:
bash
TCP 连接
└─ 多个 stream(流,一条双向虚拟通道,对应一个请求/响应)
└─ message(消息:一组帧组成的请求或响应)
└─ frame(帧:最小传输单位,二进制,带 stream id)- 所有帧共用一条 TCP 连接,帧头带 stream id 标识归属。
- 不同流的帧可以交错发送、到达后按 id 重组——这就是多路复用(multiplexing)。
- 二进制(长度前缀)而非文本,解析更快、更不易二义。
二、多路复用:告别多连接
bash
HTTP/1.1:请求/响应串行(或开 6 条 TCP)
HTTP/2: 一条连接,stream 1/3/5(客户端发起为奇数) 的帧交错
┌ stream1 DATA ┐┌ stream3 DATA ┐┌ stream1 DATA ┐
对端按 stream id 分别还原,互不等待好处:
- 单连接即可并发,无需域名分片、无多次握手,移动高 RTT 网络尤其省。
- 减少服务器连接数、TCP 与 TLS 握手和拥塞窗口预热成本(一个连接的 cwnd 充分增大后吞吐更高)。
- 请求不会因为队头响应慢而在应用层排队。
三、但 TCP 层队头阻塞仍在
HTTP/2 消除的是 HTTP 层队头阻塞,可所有流复用的是一条 TCP 连接:一旦某个 TCP 段丢失,整条连接在重传补齐前无法向上交付字节,于是所有 stream 一起等——这是 TCP 层队头阻塞。
- 低丢包网络(数据中心、有线)HTTP/2 通常明显更快。
- 高丢包/高 RTT(弱网)多流共用一条 TCP,可能因一次丢包卡住全部,极端情况下不如 1.1 多连接(不同连接互不影响)。
- 根治需要传输层支持"流独立",这正是 QUIC 在 UDP 上为每条流单独保证可靠交付的原因,见 HTTP/3。
四、HPACK 头部压缩
HTTP/1.1 头部纯文本、每次重复发送 cookie/UA 等大量相同字段。HTTP/2 用 HPACK:
- 静态表(常见头如
:method GET)、动态表(本次连接出现过的头)、霍夫曼编码。 - 客户端和服务端维护同一张索引表,之后只发"索引编号 + 变化值",大幅减小请求头。
- 也因此历史上有过 HPACK 压缩比被用于破解 cookie 的一类攻击(CRIME 同源思路),实现需谨慎。
五、流优先级、流控、服务器推送
- 流优先级/依赖:客户端可表达哪个资源更重要(先传 CSS/关键数据),服务端据此调度(实际部署中优先级支持被弱化)。
- 流控:基于信用的窗口机制,在流和连接两级限制未被读取的数据,避免一个快流淹没慢消费者。
- 服务器推送 Server Push:服务端可主动推客户端将要请求的资源(CSS/JS)。实践中收益不稳、易过度推送、与缓存协同复杂,Chrome 已移除、规范也已弃用,现多用
<link rel=preload>等替代。
六、协商与兼容
- 浏览器中的 HTTP/2 实际几乎都跑在 TLS 上,通过 TLS 扩展 ALPN(协商
h2,否则回退http/1.1)。 - 也有明文 h2c(Upgrade 或先验知识),主要用于服务间/代理内部。
- 方法、状态码、URL、
Content-Type等语义与 1.1 完全一致,应用改动小;但头部必须小写、使用伪头:method/:path/:scheme/:authority。
七、工程注意
- 不要再做"域名分片/spriting 拼大图/合并文件为减少连接"等为 1.1 设计的优化——在 2/3 上可能适得其反(拆成更多流反而利于优先级调度和缓存)。
- 启用 HTTP/2 后关注丢包率与 RTT;弱网场景评估 HTTP/3。
- 反代/网关(Nginx、Envoy、CDN)需开启 HTTP/2 并确认 ALPN 配置;h2 与 h1 在入口常由代理终结后转发。
- 应用层消息边界仍由 HTTP 帧/长度解决,这比裸 TCP 方便(对比粘包问题)。
相关阅读
前因 HTTP/1.1,遗留 HOL 的解法 HTTP/3 与 QUIC,方法语义见幂等,TLS 协商见 TLS 握手。
总结
HTTP/2 用二进制分帧把请求-响应拆成带 stream id 的帧,在一条 TCP 连接上多路复用,配合 HPACK 头部压缩、优先级和流控解决了 HTTP/1.1 的应用层队头阻塞与多连接开销;但所有流共享 TCP,丢包仍会阻塞全部(TCP 层 HOL),语义与 1.1 兼容、靠 TLS ALPN 协商,服务器推送已被实践弃用。