3. HTTP/2 协议特性:多路复用、流优先级、头部压缩、Server Push 及其对流控的影响

HTTP/2 协议是构建现代微服务网格与 Envoy 数据平面的核心传输基石。与 HTTP/1.1 的串行请求-响应模型不同,HTTP/2 引入了一套全新的二进制分帧层,从根本上改变了流量的并发模型与拥塞控制方式。理解这些特性,是掌握 Envoy 故障域隔离与多租户流控策略的前提。

3.1 二进制分帧与多路复用

HTTP/2 将所有通信拆分为更细粒度的 帧(Frame),并归属于不同的 流(Stream)。一个 TCP 连接上可以同时承载多个双向的流,实现真正的多路复用。

核心优势: 消除了 HTTP/1.1 的队头阻塞(HOL Blocking)问题。在 HTTP/1.1 中,一个连接只能处理一个请求,后续请求必须等待前一个响应完成;HTTP/2 允许多个请求和响应在同一个连接上交错传输,互不阻塞。
Envoy 视角: Envoy 作为 Sidecar 代理,会为每个上游集群维护一个或多个 HTTP/2 连接。多路复用意味着一个 Envoy 实例可以用极少的连接处理数千个并发请求,显著降低内存与文件描述符开销。
HTTP/2 多路复用 vs HTTP/1.1 串行阻塞 HTTP/1.1 (串行) 请求 A (等待中) 响应 A (传输中) 请求 B (阻塞) HTTP/2 (多路复用) 流 1: 请求 A (帧1) | 流 2: 请求 B (帧1) 流 1: 响应 A (帧1) | 流 3: 请求 C (帧1) 流 2: 响应 B (帧1) | 流 1: 响应 A (帧2) 关键点:HTTP/2 帧在连接上交错传输, 单个慢响应不会阻塞其他流的帧传输。

3.2 流优先级与依赖

HTTP/2 允许客户端为每个流指定优先级,通过 流依赖图 和 权重 来告知服务器资源的分配顺序。优先级信息在 HEADERS 帧中传递,并可在流生命周期内通过 PRIORITY 帧动态调整。

优先级参数 说明 对流控的影响
Stream Dependency 指定当前流依赖的父流 ID。父流完成后,子流才能获得资源。 影响 Envoy 的上游调度顺序,高优先级流获得更多带宽与窗口。
Weight 1-256 之间的整数,表示在同级流中的相对资源比例。 Envoy 的 HTTP/2 连接管理器会根据权重分配流控窗口。
Exclusive Flag 若为 true,当前流成为父流的唯一子流,其他同级流被重新挂载。 可用于实现租户隔离:一个租户的流独占一个优先级子树。
多租户风险: 恶意或配置错误的客户端可能通过声明高优先级来抢占带宽,导致其他租户的请求被饿死。Envoy 可以通过 http2_protocol_options 中的 override_stream_priority 或自定义过滤器来重写或忽略客户端优先级,实施服务端主导的公平调度。

3.3 头部压缩(HPACK)

HTTP/2 使用 HPACK 算法对头部进行压缩,通过静态表、动态表和 Huffman 编码大幅减少冗余头部开销。这对于微服务场景至关重要,因为每个请求通常携带大量相同的元数据(如 :authority、content-type、trace ID)。

  • 静态表: 预定义了 61 个常用头部字段(如 :method: GET),只需 1 字节索引即可表示。
  • 动态表: 客户端和服务器共同维护,用于缓存之前发送过的自定义头部。大小由 SETTINGS_HEADER_TABLE_SIZE 控制。
  • Huffman 编码: 对字符串值进行压缩,进一步减少字节数。
对流控的影响: 头部压缩减少了每个流的数据量,使得流控窗口可以容纳更多请求。但动态表的大小直接影响内存占用。在多租户场景下,如果所有租户共享同一个 HTTP/2 连接,一个租户的头部可能会污染动态表,导致另一个租户的头部压缩效率下降。Envoy 可以通过为不同租户建立独立连接来隔离动态表。

3.4 Server Push

Server Push 允许服务器在客户端明确请求之前,主动向客户端推送资源。服务器发送 PUSH_PROMISE 帧,告知客户端即将推送的流。

特性 说明 多租户流控考量
PUSH_PROMISE 在响应流中发送,包含被推送资源的头部。 Envoy 默认禁用 Server Push(envoy.reloadable_features.http2_protocol_options.allow_push)。
资源竞争 推送的流会占用连接的总流控窗口和并发流限制。 若一个租户的请求触发大量推送,可能耗尽连接资源,影响其他租户。
故障域 推送流与原始请求流共享同一个连接的生命周期。 连接故障会导致所有推送流中断,不适合跨故障域推送。
Envoy 最佳实践: 在网格代理层面,通常禁用 Server Push 以避免不可控的资源消耗。如果业务需要,建议为推送资源设置独立的流优先级,并限制每个连接的最大并发推送流数。

3.5 流控机制的综合影响

HTTP/2 的流控是基于 信用(Credit) 的窗口更新机制。每个流和整个连接都有独立的流控窗口。上述特性对流控的影响总结如下:

HTTP/2 特性对流控窗口的影响 流控窗口管理 多路复用 窗口在流间共享 流优先级 高权重流获更多信用 头部压缩 减少帧大小,窗口利用率高 Server Push 消耗连接级窗口 多租户流控设计要点 • 连接级窗口:所有租户共享,需设置合理上限防止单个租户耗尽。 • 流级窗口:Envoy 可基于租户权重动态调整每个流的初始窗口。 • 优先级重写:服务端强制覆盖客户端优先级,实现公平调度。

3.6 多租户场景下的关键配置

在 Envoy 中,针对 HTTP/2 流控的故障域隔离,以下配置参数至关重要:

# Envoy HTTP/2 连接管理器配置片段
http2_protocol_options:
  max_concurrent_streams: 100          # 每个连接最大并发流数,防止单租户耗尽连接
  initial_stream_window_size: 65535    # 每个流的初始窗口大小(字节)
  initial_connection_window_size: 1048576  # 连接级初始窗口(1MB)
  override_stream_priority: true       # 服务端覆盖客户端优先级
  allow_push: false                    # 禁用 Server Push
  max_inbound_header_size: 8192        # 限制头部大小,防止 HPACK 攻击
故障边界测试提示: 在测试多租户隔离时,应构造一个租户发送大量低优先级大请求、另一个租户发送高优先级小请求的场景。观察 Envoy 是否能够通过流控窗口和优先级调度,保证高优先级租户的延迟不受影响。这是验证 HTTP/2 流控隔离有效性的核心测试用例。