2. Envoy 架构基础:线程模型、Listener/Cluster/Endpoint 配置与 L4/L7 过滤器链机制

Envoy 作为高性能服务网格数据面,其架构设计围绕非阻塞事件驱动与多级过滤器链展开。理解线程模型、核心资源(Listener/Cluster/Endpoint)以及 L4/L7 过滤器链机制,是编写自定义扩展过滤器和集成策略即代码(Policy as Code)资源配额模型的前提。

2.1 Envoy 线程模型:主线程与 Worker 线程

Envoy 采用单进程多线程架构,通过 主线程(Main Thread) 与多个 Worker 线程 实现高并发与配置热更新。所有 Worker 线程共享底层连接池和内存,但各自持有独立的事件循环和连接状态,避免锁竞争。

关键设计原则: 主线程负责配置管理和统计聚合;Worker 线程负责实际的数据面流量处理。配置更新通过“热交换”机制(Hot Restart / LDS/CDS 推送)无缝同步到所有 Worker。
Envoy 线程模型架构 主线程 配置管理 / 统计 / 集群管理 配置分发总线 Worker 线程池 (通常 = CPU 核心数) Worker 0 事件循环 + 连接处理 Worker 1 事件循环 + 连接处理 Worker 2 事件循环 + 连接处理 Worker N 事件循环 + 连接处理 共享内存区域 连接池 · 集群健康检查 · 统计计数器 💡 说明: 主线程通过 xDS (LDS/CDS/RDS/EDS) 接收控制面配置,序列化为内部数据结构后原子性更新到每个 Worker 的共享内存区域。

2.2 核心配置资源:Listener、Cluster、Endpoint

Envoy 的配置模型围绕三个核心资源构建,它们构成了流量路由的骨架。下表总结了每个资源的作用与关键属性:

资源 作用 关键配置属性 动态更新 API
Listener 定义 Envoy 监听的端口和协议(TCP/UDP),是流量的入口。 address(监听地址)、filter_chains(过滤器链)、listener_filters(监听器过滤器) LDS (Listener Discovery Service)
Cluster 定义上游服务集群的配置,包括连接池、负载均衡策略、健康检查。 type(STRICT_DNS/EDS/STATIC)、connect_timeout、lb_policy(ROUND_ROBIN/LEAST_REQUEST) CDS (Cluster Discovery Service)
Endpoint Cluster 中的具体后端实例(IP:Port),包含健康状态和权重。 address、health_status、load_balancing_weight EDS (Endpoint Discovery Service)
实践要点: 在集成策略即代码资源配额模型时,通常会在 Listener 的 filter_chains 中插入自定义 L4 过滤器(用于解析协议元数据),或在 HTTP 连接管理器(HCM) 的 L7 过滤器链中插入配额检查过滤器。Cluster 和 Endpoint 则用于将超限请求转发到限流服务或降级响应。

2.3 L4 过滤器链机制

L4 过滤器链工作在传输层(TCP/UDP),在连接建立阶段和数据处理阶段执行。每个 Listener 可以配置多个 filter_chains,Envoy 根据连接的目标端口、SNI(Server Name Indication)或源 IP 匹配对应的链。

  • 监听器过滤器(Listener Filters):在连接被接受后、网络过滤器链处理之前执行。常用于 TLS 终止、代理协议解析、原始目的地检测。
  • 网络过滤器(Network Filters):构成 L4 过滤器链的核心。常见的网络过滤器包括 TCP 代理(TCP Proxy)、直接响应(Direct Response)、以及自定义的 L4 过滤器。
  • 数据流回调:L4 过滤器通过 onNewConnection()、onData()、onEvent() 等回调函数参与连接生命周期。
# 示例:L4 过滤器链配置片段(YAML)
listener:
  name: my_tcp_listener
  address:
    socket_address: { address: 0.0.0.0, port_value: 10000 }
  filter_chains:
  - filters:
    - name: envoy.filters.network.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: tcp_service
        cluster: my_upstream_cluster
    # 自定义 L4 过滤器示例(用于提取连接元数据)
    - name: my_custom_l4_filter
      typed_config:
        "@type": type.googleapis.com/my_package.v3.CustomL4Filter
        metadata_key: connection_quota_key

2.4 L7 过滤器链机制(HTTP 连接管理器)

L7 过滤器链工作在应用层(HTTP/2、HTTP/1.1、gRPC),通过 HTTP 连接管理器(HCM) 实现。HCM 本身是一个 L4 网络过滤器,它负责将原始字节流解码为 HTTP 请求/响应,然后交给内部的 L7 过滤器链处理。

L7 过滤器链的执行顺序严格按配置顺序排列,每个过滤器可以读取、修改或终止请求/响应。常见的 L7 过滤器包括:

  • Router(路由器):负责将请求路由到目标 Cluster,是链中最后一个核心过滤器。
  • RBAC(基于角色的访问控制):执行授权策略。
  • Rate Limit(速率限制):执行全局或本地速率限制。
  • 自定义 L7 过滤器:用于集成策略即代码引擎,执行资源配额检查。
L7 过滤器链(HTTP 连接管理器内部) 入站请求 HTTP 解码器 RBAC 过滤器 配额检查过滤器 自定义策略过滤器 Router 过滤器 出站请求 💡 执行顺序: 请求按配置顺序经过解码器 → 过滤器 1 → 过滤器 2 → ... → Router。任一过滤器可以停止遍历并直接返回响应(如配额不足时返回 429)。

2.5 过滤器链与策略即代码的集成点

在资源配额模型集成中,L4 和 L7 过滤器链提供了两个关键的扩展点:

集成层级 适用场景 数据来源 典型动作
L4 网络过滤器 基于连接粒度的配额(如每秒连接数、并发连接数) 源 IP、SNI、连接元数据 拒绝连接、记录连接日志、更新连接计数器
L7 HTTP 过滤器 基于请求粒度的配额(如每分钟 API 调用次数、用户级别配额) HTTP Header、Path、JWT Claims、gRPC Metadata 返回 429 Too Many Requests、添加重试 Header、调用配额服务
性能注意事项: 自定义过滤器应避免在关键路径上执行阻塞 I/O 操作。对于策略即代码引擎的调用,建议使用异步回调或线程池,并启用连接池复用。在 L7 过滤器中,优先使用 decoderHeaders() 阶段进行配额检查,以尽早拒绝超限请求,减少不必要的解码开销。