Skip to content

HTTP/2 协议深度解析

1. 二进制分帧层 (Binary Framing Layer)

HTTP/2 将 HTTP 消息分解为帧 (Frame),是协议的最小传输单位。

帧结构 (9 字节头 + Payload)

+-----------------------------------------------+
|                 Length (24)                   |
+---------------+---------------+---------------+
|   Type (8)    |   Flags (8)   |
+-+-------------+---------------+-------------------------------+
|R|                 Stream Identifier (31)                      |
+=+=============================================================+
|                   Frame Payload (0...)                      ...
+---------------------------------------------------------------+
  • Length: Payload 长度 (最大 16KB,可配置到 16MB)
  • Type: 帧类型
  • Flags: 标志位 (如 END_STREAM, END_HEADERS)
  • Stream ID: 流标识符 (0 表示连接级别)

常见帧类型

Type名称用途
0x0DATA传输 HTTP Body
0x1HEADERS传输 HTTP Headers (使用 HPACK 压缩)
0x2PRIORITY流优先级 (已废弃,HTTP/3 移除)
0x3RST_STREAM终止流
0x4SETTINGS配置参数 (如最大并发流数)
0x5PUSH_PROMISE服务器推送
0x6PING心跳 / RTT 测量
0x7GOAWAY优雅关闭连接
0x8WINDOW_UPDATE流量控制

2. 流 (Stream) 与多路复用

Stream 是什么?

  • 一个 逻辑上的双向字节流
  • 每个 HTTP 请求/响应是一个 Stream
  • 多个 Stream 在同一个 TCP 连接上并发传输

Stream 生命周期

                          +--------+
                  send PP |        | recv PP
                 ,--------|  idle  |--------.
                /         |        |         \
               v          +--------+          v
        +----------+          |           +----------+
        |          |          | send H /  |          |
,------| reserved |          | recv H    | reserved |------.
|      | (local)  |          |           | (remote) |      |
|      +----------+          v           +----------+      |
|          |             +--------+             |          |
|          |     recv ES |        | send ES     |          |
|   send H |     ,-------|  open  |-------.     | recv H   |
|          |    /        |        |        \    |          |
|          v   v         +--------+         v   v          |
|      +----------+          |           +----------+      |
|      |   half   |          |           |   half   |      |
|      |  closed  |          | send R /  |  closed  |      |
|      | (remote) |          | recv R    | (local)  |      |
|      +----------+          |           +----------+      |
|           |                |                 |           |
|           | send ES /      |       recv ES / |           |
|           | send R /       v        send R / |           |
|           | recv R     +--------+   recv R   |           |
| send R /  `----------->|        |<-----------'  send R / |
| recv R                 | closed |               recv R   |
`----------------------->|        |<-----------------------'
                         +--------+

多路复用优势

  • 消除队头阻塞 (HOL Blocking): 应用层面
  • 减少连接数: 单连接处理所有请求
  • Header 压缩: HPACK 算法

3. HPACK 头部压缩

核心思想

  1. 静态表: 预定义 61 个常见 Header (如 :method: GET)
  2. 动态表: 连接级缓存,存储已传输的 Header
  3. Huffman 编码: 压缩 Header 值

示例

首次请求: User-Agent: Mozilla/5.0... (完整传输,加入动态表) 后续请求: 只需传输索引号 (如 62)


4. 流量控制 (Flow Control)

  • 基于 WINDOW_UPDATE
  • 每个 Stream 和整个连接都有独立的窗口
  • 防止快速发送方压垮慢速接收方

5. HTTP/2 的局限 → HTTP/3

尽管解决了应用层队头阻塞,TCP 层队头阻塞仍然存在:

  • 一个 TCP 包丢失,所有 Stream 都被阻塞
  • 解决方案: HTTP/3 基于 UDP (QUIC)

前端面试知识库