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 重组数据,实现真正的并发复用。
HTTP/1.1 串行 vs HTTP/2 多路复用 HTTP/1.1 — 串行阻塞 请求 1 (Stream 1) — 发送中 请求 2 (Stream 2) — 等待 请求 3 (Stream 3) — 等待 HTTP/2 — 多路复用 流 1 流 2 流 3 流 2 流 3 流 1 流 3 流 1 流 2 HTTP/2 帧交错:不同流的 DATA 帧可以在连接上交替发送, 接收方通过 Stream ID 重组,消除队头阻塞。 ✗ 串行:1 个请求阻塞整条连接 ✓ 并发:多个流共享连接带宽 连接利用率低,延迟累积 连接利用率高,延迟降低

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)两个级别独立运作。

HTTP/2 双层流量控制窗口模型 连接级流量控制窗口 (Connection Window) 初始大小:65535 字节(64 KB)— 控制整个连接上所有流的总未确认数据量 可用信用:32 KB 已使用:20 KB 已耗尽:12 KB 流级流量控制窗口 (Stream Window) 每个流独立维护窗口,初始大小通常也为 64 KB 流 1 (租户 A) 窗口:40 KB / 64 KB 流 2 (租户 B) 窗口:10 KB / 64 KB 流 3 (租户 C) 窗口:64 KB / 64 KB WINDOW_UPDATE 帧:接收方处理完数据后发送,增加窗口信用,允许发送方继续发送。

3.3.1 窗口更新与背压传播

流量控制的核心交互流程如下:

  1. 发送方每发送一个 DATA 帧,从对应流窗口和连接窗口中扣除相同字节数。
  2. 接收方处理完数据后,发送 WINDOW_UPDATE 帧,增加窗口信用。
  3. 当流窗口耗尽时,该流暂停发送;当连接窗口耗尽时,整个连接暂停发送。
  4. 这种双层机制允许接收方精细控制:即使连接窗口充足,单个慢速流也不会被饿死。
多租户隔离陷阱:如果某个租户的流处理缓慢(例如后端响应延迟高),其流窗口会迅速耗尽。但若连接窗口仍被该租户的未确认数据占用,其他租户的流将因连接窗口不足而无法发送,造成租户间干扰。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 的 动态转发 和 速率限制过滤器 可进一步强化租户隔离。

3.6 小结