2. Envoy 架构解析:工作线程模型、核心组件与配置热加载
Envoy 作为高性能的七层代理,其架构设计围绕三个核心目标展开:高吞吐、低延迟与动态可扩展。本章深入剖析 Envoy 的工作线程模型、四大核心组件(Listener、Filter、Cluster)以及控制面数据面协同机制(RDS/CDS),并解析其配置热加载的实现原理。
2.1 工作线程模型:从主线程到 Worker 池
Envoy 采用 单进程多线程 架构,主线程负责配置管理与协调,Worker 线程负责实际的数据平面转发。这种模型避免了多进程架构的上下文切换开销,同时通过线程绑定(Thread Affinity)最大化 CPU 缓存命中率。
--concurrency 参数调整。每个 Worker 线程拥有独立的连接池和事件循环,无需加锁即可处理大部分请求。
2.2 核心组件:Listener、Filter、Cluster
Envoy 的数据处理流水线由三个核心组件构成,它们共同定义了流量从入站到出站的完整路径。
| 组件 | 职责 | 关键配置项 | 生命周期 |
|---|---|---|---|
| Listener | 监听端口,接受入站连接 | 地址、端口、协议(TCP/UDP)、TLS 设置 | 每个 Worker 独立监听 |
| Filter | 处理请求/响应的中间件链 | HTTP 过滤器(Router、RBAC、Rate Limit)、网络过滤器 | 按 Listener 或 Route 配置 |
| Cluster | 定义上游服务端点及负载均衡策略 | 端点列表、健康检查、负载均衡算法、连接池 | 全局共享,动态更新 |
2.2.1 Listener:流量入口
Listener 是 Envoy 对外暴露的端口抽象。每个 Listener 绑定一个 IP:Port,并指定使用的网络协议栈。Envoy 支持 TCP Listener 和 UDP Listener,以及通过 reuse_port 选项实现多 Worker 共享端口。
static_resources:
listeners:
- name: ingress_http
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config_name: local_route
http_filters:
- name: envoy.filters.http.router
2.2.2 Filter:处理链
Filter 是 Envoy 可扩展性的核心。请求经过 Listener 后,会依次通过 网络过滤器(Network Filter) 和 HTTP 过滤器(HTTP Filter) 链。每个过滤器可以修改请求、生成响应或终止连接。
- 网络过滤器: 工作在 L4 层,处理原始字节流,如 TCP 代理、TLS 终止。
- HTTP 过滤器: 工作在 L7 层,处理 HTTP 请求/响应,如 Router、CORS、RBAC、Rate Limit。
- 过滤器链顺序: 顺序敏感,Router 过滤器通常放在最后,负责将请求转发到 Cluster。
2.2.3 Cluster:上游服务抽象
Cluster 定义了 Envoy 如何连接到上游服务。每个 Cluster 包含一组端点(Endpoint)、健康检查策略、负载均衡算法以及连接池配置。
static_resources:
clusters:
- name: service_backend
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: backend.example.com
port_value: 80
health_checks:
- timeout: 1s
interval: 5s
unhealthy_threshold: 3
healthy_threshold: 2
http_health_check:
path: /health
type 字段决定了端点发现方式(STATIC、STRICT_DNS、LOGICAL_DNS、EDS)。在 Kubernetes 环境中,推荐使用 EDS(端点发现服务)以实现动态端点更新。
2.3 控制面协同:RDS 与 CDS
Envoy 通过 xDS 协议 从控制面(如 Istio Pilot)动态获取配置。其中 RDS(Route Discovery Service) 和 CDS(Cluster Discovery Service) 是最核心的两个发现服务。
| 发现服务 | 资源类型 | 更新频率 | 典型场景 |
|---|---|---|---|
| RDS | 路由配置(VirtualHost、Route、Match) | 按需推送(秒级) | 灰度发布、流量镜像、Header 路由 |
| CDS | 集群定义(端点、负载均衡、健康检查) | 按需推送(秒级) | 服务扩缩容、故障隔离、集群迁移 |
| EDS | 端点列表(IP:Port、权重、区域) | 高频推送(毫秒级) | Pod 滚动更新、自动扩缩容 |
| LDS | 监听器配置(端口、TLS、Filter 链) | 低频推送 | 新增端口、TLS 证书轮换 |
2.4 配置热加载机制
Envoy 支持两种配置热加载方式:热重启(Hot Restart) 和 动态 xDS 更新。前者适用于静态配置文件变更,后者适用于控制面驱动的动态配置。
2.4.1 热重启机制
当 Envoy 通过 SIGHUP 信号触发热重启时,旧进程会保持现有连接,新进程加载新配置并接管新连接。两个进程通过 共享内存(Shared Memory) 和 Unix Domain Socket 进行连接迁移。
# 触发热重启
kill -SIGHUP <envoy_pid>
# 热重启流程
1. 新进程启动,绑定到相同端口(通过 SO_REUSEPORT)
2. 新进程从旧进程通过 UDS 获取监听器状态
3. 旧进程停止接受新连接,等待现有连接处理完毕
4. 旧进程优雅退出,新进程完全接管
2.4.2 动态 xDS 更新
在 Istio 环境中,配置热加载主要通过 xDS 协议实现。Envoy 与控制面建立 gRPC 流,控制面推送增量更新,Envoy 在 Worker 线程中无锁更新共享内存中的配置。
- 增量推送: 控制面只推送变更的资源,减少网络开销。
- 版本控制: 每个资源携带版本号,Envoy 通过 ACK/NACK 机制确认更新状态。
- 优雅降级: 如果新配置导致连接失败,Envoy 会回滚到上一个可用版本。
2.5 本章小结
Envoy 的架构设计体现了现代代理软件的高性能与可扩展性要求:
- 工作线程模型 通过主线程与 Worker 线程分离,实现控制面与数据面解耦。
- Listener/Filter/Cluster 构成完整的数据处理流水线,Filter 链提供了灵活的扩展点。
- RDS/CDS 等 xDS 协议实现了控制面与数据面的动态协同,是 Istio 服务网格的核心通信机制。
- 配置热加载 支持热重启与动态更新两种模式,满足不同场景下的配置变更需求。