3. HTTP/2 协议核心:多路复用、流优先级、流量控制窗口
HTTP/2 是 Envoy 数据面处理多租户流量的核心协议。与 HTTP/1.1 的串行模型不同,HTTP/2 通过单一 TCP 连接上的多路复用、流优先级调度和双层流量控制窗口,实现了更高的并发效率与更精细的资源隔离。理解这些机制是构建租户故障域的基础。
3.1 多路复用:从串行到并发
HTTP/1.1 的队头阻塞(Head-of-Line Blocking)问题源于其请求-响应模型:同一连接上,前一个请求未完成时,后续请求必须等待。HTTP/2 引入的流(Stream)概念彻底改变了这一局面。
核心概念:每个 HTTP/2 请求-响应交换在一个独立的流中完成。多个流可以在同一个 TCP 连接上交错发送帧(Frame),接收方根据流 ID 重组数据,实现真正的并发复用。
3.2 流优先级:控制资源分配顺序
多路复用带来了新的问题:当多个流争用同一连接带宽时,如何决定哪个流的数据帧优先发送?HTTP/2 定义了流优先级机制,允许客户端或代理服务器为每个流分配权重和依赖关系。
| 优先级参数 | 说明 | Envoy 中的意义 |
|---|---|---|
| 权重 (Weight) | 1–256 的整数,表示同一依赖层级下的相对比例 | 用于租户间带宽分配比例,权重高的租户获得更多发送机会 |
| 流依赖 (Stream Dependency) | 指定当前流依赖的父流 ID,形成优先级树 | 可构建租户优先级层级:关键租户作为父节点,普通租户作为子节点 |
| 独占标志 (Exclusive) | 若为 true,当前流成为父流的唯一子节点 | 用于隔离高优先级租户,避免被同级流抢占 |
Envoy 实践提示:Envoy 的
HttpConnectionManager 支持通过 http2_protocol_options 配置流优先级策略。在多租户场景中,可以为每个租户的流设置不同的权重,实现加权公平队列(WFQ)调度。
3.3 流量控制窗口:双层背压机制
HTTP/2 的流量控制是防止接收方被数据淹没的关键。它采用基于信用(Credit-based)的滑动窗口模型,在连接(Connection)和流(Stream)两个级别独立运作。
3.3.1 窗口更新与背压传播
流量控制的核心交互流程如下:
- 发送方每发送一个 DATA 帧,从对应流窗口和连接窗口中扣除相同字节数。
- 接收方处理完数据后,发送
WINDOW_UPDATE帧,增加窗口信用。 - 当流窗口耗尽时,该流暂停发送;当连接窗口耗尽时,整个连接暂停发送。
- 这种双层机制允许接收方精细控制:即使连接窗口充足,单个慢速流也不会被饿死。
多租户隔离陷阱:如果某个租户的流处理缓慢(例如后端响应延迟高),其流窗口会迅速耗尽。但若连接窗口仍被该租户的未确认数据占用,其他租户的流将因连接窗口不足而无法发送,造成租户间干扰。Envoy 通过动态窗口调整和流级限速来缓解此问题。
3.4 HTTP/1.1 vs HTTP/2 核心对比
| 维度 | HTTP/1.1 | HTTP/2 | 对多租户的影响 |
|---|---|---|---|
| 连接模型 | 每个请求通常独占一个 TCP 连接(或少量复用) | 单一 TCP 连接承载多个并发流 | 减少连接数,但需更精细的流级隔离 |
| 队头阻塞 | 存在(应用层 HOL) | 不存在(帧交错消除 HOL) | 避免一个慢请求阻塞整个租户的连接 |
| 并发粒度 | 连接级并发(通常 6–8 个连接/域名) | 流级并发(默认 100 个并发流/连接) | 支持更多租户共享同一连接 |
| 流量控制 | 无应用层流控,依赖 TCP 接收窗口 | 双层流控(连接 + 流),基于 WINDOW_UPDATE | 可对单个租户流实施背压,防止资源滥用 |
| 优先级 | 无原生优先级,依赖连接池调度 | 权重 + 依赖树,支持精细调度 | 可为高优先级租户分配更多带宽 |
| 头部压缩 | 无(明文头部) | HPACK 压缩,减少冗余头部 | 降低多租户场景下的头部开销 |
| 服务器推送 | 不支持 | 支持(PUSH_PROMISE 帧) | 可用于预推送租户公共资源 |
3.5 Envoy 中的 HTTP/2 配置要点
在 Envoy 中,HTTP/2 协议选项通过 HttpConnectionManager 的 http2_protocol_options 字段配置。以下是与多租户故障域相关的关键参数:
http_connection_manager:
codec_type: AUTO
http2_protocol_options:
# 连接级初始窗口大小(字节),默认 65535
initial_connection_window_size: 1048576 # 1 MB
# 流级初始窗口大小(字节),默认 65535
initial_stream_window_size: 65536 # 64 KB
# 最大并发流数,默认 100
max_concurrent_streams: 200
# 是否允许连接窗口动态增长
allow_connect: true
# 自定义流优先级策略(通过扩展实现)
# 可在此处配置租户权重映射
最佳实践:对于多租户场景,建议将
initial_connection_window_size 设置为较大值(如 1 MB),避免连接窗口成为瓶颈;同时保持 initial_stream_window_size 为 64 KB,以便对单个慢速流快速施加背压。Envoy 的 动态转发 和 速率限制过滤器 可进一步强化租户隔离。