1. Service Mesh 与 Envoy 概述
1.1 Service Mesh 架构演进
Service Mesh 的出现是为了解决微服务架构中日益复杂的服务间通信问题。从最初的“胖客户端”模式到 Sidecar 代理模式,再到控制面与数据面分离的成熟形态,其演进过程可概括为三个阶段:
| 阶段 | 架构特征 | 代表技术 | 核心痛点 |
|---|---|---|---|
| 第一阶段 嵌入式治理 |
服务发现、负载均衡、熔断等逻辑内嵌在应用框架或客户端库中 | Netflix OSS (Eureka, Hystrix, Ribbon) | 语言绑定强、升级成本高、多语言支持差 |
| 第二阶段 Sidecar 代理 |
将通信治理逻辑剥离到独立进程(Sidecar),与应用容器同 Pod 部署 | Envoy + 手动配置 | 配置分散、缺乏统一控制面 |
| 第三阶段 控制面 + 数据面 |
引入集中控制面统一管理 Sidecar 配置,数据面专注高性能转发 | Istio (Pilot, Mixer, Citadel) + Envoy | 控制面复杂度上升,但治理能力大幅增强 |
关键认知:Service Mesh 的本质是将“网络通信的复杂性”从应用层剥离,下沉为基础设施层。Envoy 作为数据面代理,是这一下沉过程的核心执行者。
1.2 Envoy 在 Istio 中的角色
在 Istio 架构中,Envoy 承担了数据面的全部职责。每个服务实例的 Pod 内都运行着一个 Envoy Sidecar 代理,拦截所有进出流量。其核心角色包括:
- 流量拦截与转发:通过 iptables 规则劫持 Inbound/Outbound 流量,基于动态路由规则进行转发。
- 服务发现与负载均衡:从控制面(Pilot)获取服务端点列表,执行多种负载均衡算法(如 Maglev、Ring Hash、Least Request)。
- 熔断与连接池管理:维护上游集群的连接池(HTTP/1.1、HTTP/2、TCP),执行主动健康检查与熔断策略。
- 可观测性:自动生成访问日志、分布式追踪(Trace)和指标(Metrics),上报给 Mixer 或 Prometheus。
- 安全通信:与 Citadel 集成,实现 mTLS 加密和证书轮换。
1.3 连接池概念引入
连接池是 Envoy 管理上游服务连接的核心机制。它位于 Envoy 的 Cluster Manager 模块中,负责为每个上游集群维护一组预先建立的连接,避免每次请求都经历 TCP 三次握手和 TLS 握手的高昂开销。
1.3.1 为什么需要连接池?
- 性能优化:复用连接,减少握手延迟和 CPU 开销。
- 资源控制:限制与上游服务的并发连接数,防止下游请求洪峰压垮上游。
- 故障隔离:当上游实例异常时,连接池可以快速断开并标记该实例,避免流量持续涌入。
1.3.2 Envoy 连接池的核心类型
| 连接池类型 | 协议 | 核心参数 | 典型场景 |
|---|---|---|---|
| HTTP/2 连接池 | HTTP/2 (h2, h2c) | max_requests_per_connection, max_concurrent_streams | gRPC 服务、长连接多路复用 |
| HTTP/1.1 连接池 | HTTP/1.1 | max_connections, max_pending_requests, max_requests_per_connection | 传统 REST API、短连接服务 |
| TCP 连接池 | TCP (原始 TCP 代理) | max_connections, connect_timeout, tcp_keepalive | 数据库代理、Redis 代理、自定义 TCP 协议 |
升级故障关联:在 Service Mesh 升级过程中(例如 Istio 控制面升级或 Envoy Sidecar 版本更新),连接池的配置变更或连接状态重置是导致“流量中断”、“503 错误激增”、“连接耗尽”等故障的首要原因。理解连接池的内部状态机是排查此类问题的前提。
1.3.3 连接池的生命周期状态
Envoy 连接池并非简单的“创建-使用-销毁”模型,而是包含多个内部状态,用于精细控制连接的健康度和复用策略:
- 初始化 (Init):连接池创建,等待第一个连接建立。
- 活跃 (Active):连接池中有可用连接,正常处理请求。
- 耗尽 (Exhausted):所有连接都在使用中,且达到最大连接数限制。新请求进入等待队列(pending queue)。
- 排空 (Draining):连接池正在被销毁或重建(常见于升级场景)。现有连接继续处理已有请求,但不再接受新请求。
- 销毁 (Destroyed):所有连接关闭,连接池资源释放。
升级排空陷阱:在 Istio Sidecar 升级过程中,Envoy 会触发连接池的“排空”状态。如果排空超时(drain_timeout)设置过短,可能导致正在处理中的请求被强制中断,产生 503 响应。这是连接池故障排查中最常见的问题之一。