一、服务器端的主动消息推送
HTTP/2 的服务器主动推送 是其核心优化特性之一,指服务器在客户端未显式请求的情况下,主动向客户端发送关联资源(如 HTML 依赖的 CSS、JS),本质是请求触发的预推送,而非完全无限制的主动发送。
实现逻辑
- 触发条件 :客户端发起一个请求(如请求
index.html),服务器分析该请求的关联资源后,决定主动推送。 - 推送预告(PUSH_PROMISE 帧) :服务器先发送
PUSH_PROMISE帧,包含拟推送资源的请求头(如路径、哈希),告知客户端 "即将推送某资源"。 - 客户端的控制能力 :客户端可通过
RST_STREAM帧拒绝推送(如已缓存该资源),避免冗余传输。 - 推送的资源载体 :推送的资源以独立的
Stream(流)传输,与原请求的流并行,不阻塞正常请求。
核心价值
减少首屏加载的 RTT(往返时间),避免客户端解析 HTML 后再发起资源请求的延迟。
二、Stream 的状态变迁
HTTP/2 中,Stream(流) 是单个请求 - 响应的载体(或服务器推送的资源载体),一个 TCP 连接可承载多个流,每个流有独立的生命周期,状态变迁由帧的交互控制。
核心状态及触发条件
| 状态 | 触发操作 | 说明 |
|---|---|---|
| 空闲(Idle) | 流初始状态 | 未被使用,可被客户端 / 服务器发起 |
| 保留(Reserved) | 服务器发送 PUSH_PROMISE 帧 |
为推送资源预留流,客户端可拒绝 |
| 打开(Open) | 客户端 / 服务器发送 HEADERS 帧 |
流处于活跃状态,可传输数据 |
| 半关闭(本地 / 远程) | 发送 END_STREAM 帧 |
本地 / 远程已完成数据发送,仍可接收数据 |
| 关闭(Closed) | 双方均发送 END_STREAM,或 RST_STREAM 终止 |
流生命周期结束,资源释放 |
状态变迁的核心作用
通过状态管理实现流的并发控制、资源隔离,避免同一连接上的流互相干扰。
三、RST_STREAM 帧及常见错误码
RST_STREAM 帧是 HTTP/2 中用于主动终止某个流 的控制帧,不会关闭整个 TCP 连接,仅终止指定 Stream ID 的流,避免因单个流的错误影响其他流。
常见错误码及场景
- NO_ERROR(0x0):正常终止(如客户端取消请求)。
- PROTOCOL_ERROR(0x1):流违反 HTTP/2 协议规则(如帧顺序错误)。
- REFUSED_STREAM(0x3):客户端拒绝服务器推送的流。
- CANCEL(0x8):客户端主动取消请求(如用户关闭页面)。
- COMPRESSION_ERROR(0x4):HPACK 头部压缩 / 解压缩失败。
作用
快速释放异常流的资源,提升连接的稳定性和资源利用率。
四、Stream 优先级与资源分配规则
HTTP/2 允许客户端为流指定优先级,服务器根据优先级调整资源(带宽、CPU)的分配顺序,优化关键资源的加载速度。
优先级的核心要素
- 权重(Weight):取值 1~256,权重越高,分配的资源越多。
- 依赖(Dependency):流可依赖其他流,被依赖的流优先处理(如 CSS 流依赖 HTML 流)。
资源分配规则
- 服务器按流的优先级 + 依赖关系排序,优先处理高权重、无依赖的流。
- 支持动态调整优先级(客户端发送
PRIORITY帧),适配页面加载的实时需求。