4. Envoy HTTP/2 连接管理:连接池、并发流限制、初始流窗口大小、动态窗口更新
在 Envoy 的故障域隔离与多租户场景中,HTTP/2 连接管理是保障资源公平性、防止“吵闹邻居”效应的核心机制。本章深入剖析 Envoy 如何通过连接池、并发流限制、初始流窗口大小及动态窗口更新,实现对上游集群的精细化流量控制。
4.1 连接池架构与多路复用
Envoy 为每个上游集群维护一个 HTTP/2 连接池。与 HTTP/1.1 的短连接或 Keep-Alive 不同,HTTP/2 连接池的核心优势在于多路复用:单个 TCP 连接可以承载多个并发的请求-响应流,大幅减少连接建立开销。
连接池的关键参数如下表所示:
| 参数 | 默认值 | 说明 |
|---|---|---|
max_requests_per_connection |
无限制 | 单个连接上允许的最大请求数,达到后连接将被关闭并重建 |
max_connection_duration |
无限制 | 连接的最大存活时间,用于定期刷新连接 |
idle_timeout |
1小时 | 连接空闲超时,超时后连接将被回收 |
connect_timeout |
5秒 | 建立 TCP 连接的超时时间 |
4.2 并发流限制:防止上游过载
HTTP/2 协议允许客户端在单个连接上发起多个并发流,但 Envoy 作为代理,必须对并发流数量进行限制,以防止上游服务被突发流量压垮。Envoy 通过 max_concurrent_streams 参数控制每个连接上允许的最大并发流数量。
并发流限制的工作流程如下:
- 连接建立:Envoy 与上游建立 HTTP/2 连接时,会协商
SETTINGS_MAX_CONCURRENT_STREAMS参数。 - 流调度:当请求到达时,Envoy 检查当前连接上的活跃流数量是否已达到上限。
- 排队或新建连接:如果达到上限,请求将被放入等待队列,或触发新建连接(如果连接池允许)。
- 流完成:上游响应完成后,流被关闭,释放一个并发流槽位,等待队列中的请求被调度。
upstream_rq_pending_total 和 upstream_rq_pending_overflow 指标,用于监控请求排队和溢出情况。当 upstream_rq_pending_overflow 持续增长时,说明并发流限制过小或上游处理能力不足。
4.3 初始流窗口大小与流量控制
HTTP/2 的流量控制基于窗口更新机制,每个流和整个连接都有独立的窗口大小。Envoy 允许用户配置初始流窗口大小(initial_stream_window_size)和初始连接窗口大小(initial_connection_window_size),以控制数据发送速率。
窗口大小的作用如下:
- 流级别窗口:控制单个流上的数据发送量,防止某个慢速消费者占用过多缓冲区。
- 连接级别窗口:控制整个连接上的总数据发送量,防止连接级拥塞。
Envoy 的默认窗口大小与 HTTP/2 协议默认值一致(流窗口 64KB,连接窗口 64KB),但在高吞吐场景下,通常需要调大窗口以减少往返延迟的影响。
| 场景 | 推荐流窗口大小 | 推荐连接窗口大小 |
|---|---|---|
| 低延迟、小请求 | 64KB - 256KB | 1MB |
| 高吞吐、大文件 | 1MB - 16MB | 64MB - 256MB |
| 多租户隔离 | 256KB - 1MB | 16MB |
4.4 动态窗口更新与自适应流控
Envoy 支持动态窗口更新机制,允许根据上游服务的处理速度自适应调整窗口大小。这一机制通过 http2_protocol_options 中的 dynamic_window_update 参数启用。
动态窗口更新的核心逻辑如下:
- 初始窗口:使用配置的初始流窗口大小。
- 数据消费:上游服务消费数据后,Envoy 收到
WINDOW_UPDATE帧。 - 窗口增长:如果上游消费速度较快,Envoy 会主动发送更大的
WINDOW_UPDATE,扩大窗口。 - 窗口收缩:如果上游消费速度变慢或出现背压,Envoy 会减少窗口更新量,甚至暂停发送。
下图展示了 Envoy 与上游之间的 HTTP/2 流控交互过程:
4.5 多租户场景下的配置示例
以下是一个针对多租户场景的 Envoy 配置片段,展示了如何为不同租户设置独立的连接管理参数:
static_resources:
clusters:
- name: tenant_a_cluster
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536 # 64KB
initial_connection_window_size: 1048576 # 1MB
dynamic_window_update: true
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 200
max_pending_requests: 100
max_requests: 1000
max_retries: 3
- name: tenant_b_cluster
connect_timeout: 3s
type: STRICT_DNS
lb_policy: LEAST_REQUEST
http2_protocol_options:
max_concurrent_streams: 50
initial_stream_window_size: 131072 # 128KB
initial_connection_window_size: 2097152 # 2MB
dynamic_window_update: true
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 100
max_pending_requests: 50
max_requests: 500
max_retries: 2
4.6 故障域隔离中的连接管理策略
在故障域隔离场景中,连接管理需要与故障域边界对齐。Envoy 支持通过 locality_weighted_lb 和 priority 等机制,将连接池与故障域绑定。
下表总结了不同故障域隔离策略下的连接管理要点:
| 隔离策略 | 连接池配置 | 流控参数 | 故障处理 |
|---|---|---|---|
| 按租户隔离 | 每个租户独立连接池 | 租户级并发流限制 | 租户故障不影响其他租户 |
| 按可用区隔离 | 每个可用区独立连接池 | 可用区级窗口大小 | 可用区故障自动切换 |
| 按优先级隔离 | 共享连接池,优先级队列 | 高优先级流窗口更大 | 低优先级请求被降级或丢弃 |
通过合理配置 HTTP/2 连接管理参数,Envoy 能够在多租户环境中实现精细化的流量控制,确保每个故障域内的资源使用符合预期,从而构建稳定、可预测的云原生服务网格。