土法炼钢兴趣小组的算法知识备份

【网络工程】Envoy 架构剖析:xDS、Filter Chain 与热重启

文章导航

分类入口
network
标签入口
#envoy#proxy#service-mesh#xds#filter-chain

目录

Envoy 是由 Lyft 开发、CNCF 毕业的高性能代理。与 Nginx 和 HAProxy 这些”配置文件驱动”的传统代理不同,Envoy 的核心设计理念是API 驱动的动态配置——通过 xDS(x Discovery Service)协议,控制面可以在运行时动态推送路由规则、集群配置和安全策略,不需要重启或 reload。

这个设计让 Envoy 成为 Istio、Consul Connect 等 Service Mesh 的标准数据面。但 Envoy 并不只是 Service Mesh 的组件——它本身就是一个功能强大的 L4/L7 代理,可以独立用作 API 网关、边缘代理或负载均衡器。

一、线程模型

1.1 per-Worker 事件循环

Envoy 使用单进程多线程模型,每个 Worker 线程运行独立的事件循环(基于 libevent):

                    ┌──────────────────────┐
                    │    Main Thread       │
                    │  - xDS 通信          │
                    │  - 配置管理          │
                    │  - Stats 刷新        │
                    │  - 运行时配置        │
                    └──────────┬───────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
     ┌────────┴──────┐ ┌──────┴──────┐ ┌───────┴─────┐
     │  Worker #0    │ │  Worker #1  │ │  Worker #2  │
     │  - Listener   │ │  - Listener │ │  - Listener │
     │  - L4 Filter  │ │  - L4 Filter│ │  - L4 Filter│
     │  - L7 Filter  │ │  - L7 Filter│ │  - L7 Filter│
     │  - 连接管理   │ │  - 连接管理  │ │  - 连接管理  │
     │  - libevent   │ │  - libevent │ │  - libevent │
     └───────────────┘ └─────────────┘ └─────────────┘

关键设计原则

  1. 几乎无锁:每个 Worker 线程拥有独立的连接和请求状态,不与其他 Worker 共享。这消除了大部分锁竞争。
  2. Main 线程不处理数据面流量:Main 线程只负责控制面操作(xDS、配置更新、统计聚合)。
  3. Thread Local Storage(TLS):配置更新通过 TLS 机制从 Main 线程分发到 Worker 线程,使用引用计数和只读快照,Worker 无需加锁。
# Envoy Worker 配置
# envoy.yaml
admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

# Worker 数自动设置为 CPU 核心数
# 也可以通过 --concurrency 参数指定
# envoy --concurrency 4
# 查看 Envoy 线程
ps -T -p $(pgrep envoy) | head -10
# PID    SPID   TTY   TIME CMD
# 1234   1234   ?     00:00:01 envoy         (main thread)
# 1234   1235   ?     00:00:05 envoy         (worker 0)
# 1234   1236   ?     00:00:05 envoy         (worker 1)
# 1234   1237   ?     00:00:05 envoy         (worker 2)
# 1234   1238   ?     00:00:05 envoy         (worker 3)

# 查看各线程 CPU 使用
top -H -p $(pgrep envoy)

1.2 连接与请求的处理

新连接到达:
  1. 内核通过 SO_REUSEPORT 将连接分配给某个 Worker
  2. Worker 的 Listener 接受连接
  3. 创建 Connection 对象(绑定到该 Worker)
  4. 该连接的所有后续操作都在同一个 Worker 中处理

一个 HTTP 请求的处理:
  Worker 线程
    │
    ├── Listener (TCP accept)
    │
    ├── L4 Filter Chain
    │   ├── TLS Inspector (检测是否 TLS)
    │   ├── HTTP Inspector (检测 HTTP 协议版本)
    │   └── TCP Proxy / HTTP Connection Manager
    │
    ├── HTTP Connection Manager
    │   ├── Codec (HTTP/1.1 或 HTTP/2 解码)
    │   ├── L7 Filter Chain
    │   │   ├── CORS Filter
    │   │   ├── CSRF Filter
    │   │   ├── Rate Limit Filter
    │   │   ├── JWT Auth Filter
    │   │   ├── RBAC Filter
    │   │   └── Router Filter (最终路由)
    │   │
    │   └── Router → Cluster → Endpoint
    │       ├── 负载均衡选择后端
    │       ├── 连接池获取/创建连接
    │       ├── 发送请求,接收响应
    │       └── 执行重试/超时策略
    │
    └── 响应返回客户端

1.3 与 Nginx/HAProxy 的对比

维度 Nginx HAProxy Envoy
进程/线程 多进程 单进程多线程 单进程多线程
事件库 自研 自研 libevent
Worker 间通信 共享内存 线程内存共享 TLS + 引用计数
配置更新 reload(fork 新 Worker) reload(fd 传递) xDS 热更新
语言 C C C++
扩展机制 C 模块 C 模块 Filter(C++/Wasm/Lua)
API 驱动 商业版 Runtime API xDS(原生)
HTTP/2 上游 有限 有限 完整支持

二、Filter Chain

2.1 Filter 的分层

Envoy 的扩展性完全基于 Filter Chain——所有功能(包括 HTTP 路由本身)都是通过 Filter 实现的:

L4 (Network) Filters:
  ├── TLS Inspector         — 检测 TLS 协议
  ├── HTTP Inspector        — 检测 HTTP 版本
  ├── TCP Proxy             — L4 代理
  ├── Redis Proxy           — Redis 协议代理
  ├── MySQL Proxy           — MySQL 协议代理
  ├── Mongo Proxy           — MongoDB 协议代理
  └── HTTP Connection Manager — HTTP L7 处理入口

L7 (HTTP) Filters:
  ├── Router                — HTTP 路由(必须是最后一个)
  ├── CORS                  — 跨域资源共享
  ├── CSRF                  — 跨站请求伪造防护
  ├── Rate Limit            — 速率限制
  ├── JWT Authentication    — JWT 认证
  ├── RBAC                  — 基于角色的访问控制
  ├── External Authorization — 外部认证服务
  ├── Compressor            — 响应压缩
  ├── Lua                   — Lua 脚本扩展
  ├── Wasm                  — WebAssembly 扩展
  └── Header Manipulation   — 请求/响应头修改

2.2 完整配置示例

# envoy.yaml — 完整的 L7 代理配置
static_resources:
  listeners:
    - name: http_listener
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8080
      filter_chains:
        - filters:
            # L4 Filter: HTTP Connection Manager
            - 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
                codec_type: AUTO

                # L7 Filter Chain
                http_filters:
                  # 1. CORS
                  - name: envoy.filters.http.cors
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors

                  # 2. 限流
                  - name: envoy.filters.http.local_ratelimit
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
                      stat_prefix: http_local_rate_limiter
                      token_bucket:
                        max_tokens: 1000
                        tokens_per_fill: 100
                        fill_interval: 1s

                  # 3. JWT 认证
                  - name: envoy.filters.http.jwt_authn
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
                      providers:
                        auth0:
                          issuer: https://auth.example.com/
                          audiences: ["api.example.com"]
                          remote_jwks:
                            http_uri:
                              uri: https://auth.example.com/.well-known/jwks.json
                              cluster: auth_cluster
                              timeout: 5s
                            cache_duration: 600s
                      rules:
                        - match:
                            prefix: /api/
                          requires:
                            provider_name: auth0

                  # 4. 路由(必须是最后一个)
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

                # 路由配置
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: app
                      domains: ["*"]
                      routes:
                        - match:
                            prefix: "/api/v2/"
                          route:
                            cluster: api_v2
                            timeout: 30s
                            retry_policy:
                              retry_on: "5xx,reset,connect-failure"
                              num_retries: 2
                              per_try_timeout: 10s
                        - match:
                            prefix: "/api/"
                          route:
                            cluster: api_v1
                            timeout: 30s
                        - match:
                            prefix: "/"
                          route:
                            cluster: web_cluster
                            timeout: 15s

  clusters:
    - name: api_v2
      type: STRICT_DNS
      connect_timeout: 5s
      lb_policy: LEAST_REQUEST
      load_assignment:
        cluster_name: api_v2
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: api-v2.internal
                      port_value: 8080
      # 上游连接池
      circuit_breakers:
        thresholds:
          - max_connections: 1024
            max_pending_requests: 1024
            max_requests: 1024
            max_retries: 3

    - name: api_v1
      type: STRICT_DNS
      connect_timeout: 5s
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: api_v1
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: api-v1.internal
                      port_value: 8080

    - name: web_cluster
      type: STRICT_DNS
      connect_timeout: 5s
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: web_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: web.internal
                      port_value: 8080

2.3 Wasm Filter

WebAssembly(Wasm)是 Envoy 最具潜力的扩展机制——用任何支持编译到 Wasm 的语言编写 Filter,在运行时动态加载:

# Wasm Filter 配置
http_filters:
  - name: envoy.filters.http.wasm
    typed_config:
      "@type": type.googleapis.com/udpa.type.v1.TypedStruct
      type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
      value:
        config:
          name: "custom_auth"
          root_id: "custom_auth_root"
          vm_config:
            runtime: "envoy.wasm.runtime.v8"
            code:
              local:
                filename: "/etc/envoy/filters/custom_auth.wasm"
          configuration:
            "@type": type.googleapis.com/google.protobuf.StringValue
            value: |
              {"auth_header": "X-API-Key", "valid_keys": ["key1", "key2"]}
// Rust Wasm Filter 示例(使用 proxy-wasm SDK)
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

proxy_wasm::main! {{
    proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> {
        Box::new(AuthFilter)
    });
}}

struct AuthFilter;

impl Context for AuthFilter {}

impl HttpContext for AuthFilter {
    fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
        // 检查 API Key
        match self.get_http_request_header("X-API-Key") {
            Some(key) if key == "valid-key-123" => {
                Action::Continue
            }
            _ => {
                self.send_http_response(
                    401,
                    vec![("Content-Type", "application/json")],
                    Some(b"{\"error\": \"unauthorized\"}"),
                );
                Action::Pause
            }
        }
    }
}

三、xDS 协议族

3.1 xDS 全景

xDS 是 Envoy 的核心创新——一组 gRPC/REST API,让控制面动态推送配置到 Envoy:

xDS 协议族:
  ├── LDS (Listener Discovery Service)
  │   └── 发现 Listener 配置(端口、Filter Chain)
  │
  ├── RDS (Route Discovery Service)
  │   └── 发现路由规则(URL → Cluster 的映射)
  │
  ├── CDS (Cluster Discovery Service)
  │   └── 发现集群配置(后端服务组、LB 策略)
  │
  ├── EDS (Endpoint Discovery Service)
  │   └── 发现端点列表(具体的 IP:Port)
  │
  ├── SDS (Secret Discovery Service)
  │   └── 发现 TLS 证书和密钥
  │
  ├── ECDS (Extension Config Discovery)
  │   └── 发现 Filter 配置
  │
  └── ADS (Aggregated Discovery Service)
      └── 聚合所有 xDS 到单个 gRPC 流
          保证配置更新的顺序一致性

3.2 xDS 配置示例

# envoy.yaml — 使用 xDS 动态配置
node:
  id: "envoy-node-1"
  cluster: "web-cluster"

dynamic_resources:
  # LDS: 动态发现 Listener
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster

  # CDS: 动态发现 Cluster
  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster

static_resources:
  clusters:
    # xDS 控制面集群(这个必须是静态配置)
    - name: xds_cluster
      type: STRICT_DNS
      connect_timeout: 5s
      typed_extension_protocol_options:
        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
          "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
          explicit_http_config:
            http2_protocol_options: {}
      load_assignment:
        cluster_name: xds_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: control-plane.internal
                      port_value: 18000

3.3 xDS 更新流程

              Control Plane
              (Istio Pilot / go-control-plane)
                    │
                    │ gRPC Stream (ADS)
                    ▼
              ┌───────────┐
              │ Main Thread│
              │            │
              │ 1. 接收 xDS 更新
              │ 2. 验证配置
              │ 3. 创建新的配置快照
              │ 4. 通过 TLS 分发到 Worker
              └─────┬─────┘
                    │ Thread Local Storage
         ┌──────────┼──────────┐
         ▼          ▼          ▼
    Worker 0   Worker 1   Worker 2
    (新配置)   (新配置)   (新配置)
    
    旧配置通过引用计数自动回收
    (当所有使用旧配置的连接关闭后)

xDS 更新的关键特性

  1. 最终一致:配置更新不是原子的——不同 Worker 可能短暂使用不同版本的配置。
  2. 无连接中断:正在处理的连接继续使用旧配置,新连接使用新配置。
  3. ADS 保证顺序:通过 ADS,CDS 更新先于 EDS,确保不会路由到不存在的集群。
# 查看 Envoy 当前的动态配置
curl -s http://localhost:9901/config_dump | jq '.configs[] | .["@type"]'
# "type.googleapis.com/envoy.admin.v3.BootstrapConfigDump"
# "type.googleapis.com/envoy.admin.v3.ClustersConfigDump"
# "type.googleapis.com/envoy.admin.v3.ListenersConfigDump"
# "type.googleapis.com/envoy.admin.v3.RoutesConfigDump"

# 查看 xDS 版本信息
curl -s http://localhost:9901/config_dump?resource=dynamic_listeners | \
    jq '.configs[0].dynamic_listeners[].active_state.version_info'

3.4 go-control-plane 示例

// 简单的 xDS 控制面实现
package main

import (
    "context"
    "log"
    "net"

    clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
    corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
    endpointv3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
    "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
    "github.com/envoyproxy/go-control-plane/pkg/server/v3"
    "google.golang.org/grpc"

    discoveryv3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
)

func main() {
    // 创建配置缓存
    snapshotCache := cache.NewSnapshotCache(false, cache.IDHash{}, nil)

    // 创建配置快照
    snapshot, _ := cache.NewSnapshot("v1",
        map[string][]cache.Resource{
            // Cluster 配置
            "type.googleapis.com/envoy.config.cluster.v3.Cluster": {
                &clusterv3.Cluster{
                    Name: "app_cluster",
                    ClusterDiscoveryType: &clusterv3.Cluster_Type{
                        Type: clusterv3.Cluster_STRICT_DNS,
                    },
                    LoadAssignment: &endpointv3.ClusterLoadAssignment{
                        ClusterName: "app_cluster",
                        Endpoints: []*endpointv3.LocalityLbEndpoints{{
                            LbEndpoints: []*endpointv3.LbEndpoint{{
                                HostIdentifier: &endpointv3.LbEndpoint_Endpoint{
                                    Endpoint: &endpointv3.Endpoint{
                                        Address: &corev3.Address{
                                            Address: &corev3.Address_SocketAddress{
                                                SocketAddress: &corev3.SocketAddress{
                                                    Address: "10.0.1.1",
                                                    PortSpecifier: &corev3.SocketAddress_PortValue{
                                                        PortValue: 8080,
                                                    },
                                                },
                                            },
                                        },
                                    },
                                },
                            }},
                        }},
                    },
                },
            },
        },
    )

    // 设置快照
    snapshotCache.SetSnapshot(context.Background(), "envoy-node-1", snapshot)

    // 启动 gRPC 服务器
    srv := server.NewServer(context.Background(), snapshotCache, nil)
    grpcServer := grpc.NewServer()
    discoveryv3.RegisterAggregatedDiscoveryServiceServer(grpcServer, srv)

    lis, _ := net.Listen("tcp", ":18000")
    log.Println("xDS 控制面启动在 :18000")
    grpcServer.Serve(lis)
}

四、热重启

4.1 热重启原理

Envoy 的热重启(Hot Restart)让二进制升级或配置重载不中断任何连接:

时间线:
  T=0: 旧 Envoy (epoch 0) 正在运行
  T=1: 启动新 Envoy (epoch 1)
       新旧 Envoy 通过 Unix Domain Socket 通信
  T=2: 新 Envoy 从旧 Envoy 接收 listen socket fd
       新 Envoy 开始接受新连接
  T=3: 旧 Envoy 停止接受新连接
       旧 Envoy 进入 drain 模式
  T=drain_time: 旧 Envoy 关闭所有连接并退出
# 热重启参数
envoy -c /etc/envoy/envoy.yaml \
    --restart-epoch 0 \
    --hot-restart-version $(envoy --hot-restart-version)

# 触发热重启
# 启动新进程(epoch + 1)
envoy -c /etc/envoy/envoy-new.yaml \
    --restart-epoch 1 \
    --drain-time-s 60 \
    --parent-shutdown-time-s 90

# drain-time-s: 旧进程的排水期(停止接受新连接后等待的时间)
# parent-shutdown-time-s: 旧进程的最大存活时间

4.2 热重启的共享内存

新旧 Envoy 进程通过共享内存交换统计数据,确保热重启期间的指标不会丢失:

共享内存布局:
  ┌─────────────────────────┐
  │ Hot Restart Shared Memory│
  ├─────────────────────────┤
  │ Stats Counters           │ ← 计数器在新旧进程间累加
  │ Stats Gauges             │ ← 仪表值取最新值
  │ Stats Histograms         │
  ├─────────────────────────┤
  │ Listen Socket FDs        │ ← 通过 UDS 传递
  └─────────────────────────┘
# 查看热重启状态
curl -s http://localhost:9901/hot_restart_version
# 返回热重启兼容版本号

# 查看当前 epoch
curl -s http://localhost:9901/server_info | jq '.hot_restart_version'

4.3 Envoy 在容器环境中的热重启

在 Kubernetes 中,Envoy 通常作为 Sidecar 运行,热重启的触发方式不同:

# Istio Sidecar 中的 Envoy 热重启
# pilot-agent 管理 Envoy 的生命周期
# 当配置变化时:
# 1. pilot-agent 接收新配置
# 2. pilot-agent 通过 xDS 推送给 Envoy
# 3. Envoy 的 xDS 更新机制处理(不需要热重启)
# 4. 只有二进制升级时才需要热重启

# 手动触发 Sidecar Envoy 的热重启
kubectl exec <pod> -c istio-proxy -- \
    pilot-agent request POST /quitquitquit
# Kubelet 会重新启动 Sidecar 容器

五、可观测性

5.1 统计指标

Envoy 内置了丰富的统计指标,覆盖 Listener、Cluster、HTTP 等维度:

# 查看所有统计指标
curl -s http://localhost:9901/stats

# 按前缀过滤
curl -s http://localhost:9901/stats?filter=cluster.api_v2

# Prometheus 格式导出
curl -s http://localhost:9901/stats/prometheus

# 关键指标:
# cluster.{name}.upstream_rq_total          — 总请求数
# cluster.{name}.upstream_rq_2xx            — 2xx 响应数
# cluster.{name}.upstream_rq_5xx            — 5xx 响应数
# cluster.{name}.upstream_cx_active         — 活跃连接数
# cluster.{name}.upstream_cx_connect_fail   — 连接失败数
# cluster.{name}.upstream_rq_timeout        — 请求超时数
# cluster.{name}.upstream_rq_retry          — 重试次数
# cluster.{name}.upstream_rq_pending_active — 等待连接的请求数
# http.{stat_prefix}.downstream_rq_total    — 下游总请求数
# listener.{address}.downstream_cx_active   — 监听器活跃连接数

5.2 分布式追踪

# 配置链路追踪(Zipkin)
tracing:
  http:
    name: envoy.tracers.zipkin
    typed_config:
      "@type": type.googleapis.com/envoy.config.trace.v3.ZipkinConfig
      collector_cluster: zipkin
      collector_endpoint: "/api/v2/spans"
      collector_endpoint_version: HTTP_JSON

# HTTP Connection Manager 中启用追踪
http_connection_manager:
  tracing:
    provider:
      name: envoy.tracers.zipkin
    random_sampling:
      value: 1.0    # 100% 采样(生产环境调低)

5.3 Access Log

# 访问日志配置
http_connection_manager:
  access_log:
    - name: envoy.access_loggers.file
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
        path: /var/log/envoy/access.log
        log_format:
          json_format:
            timestamp: "%START_TIME%"
            method: "%REQ(:METHOD)%"
            path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
            protocol: "%PROTOCOL%"
            response_code: "%RESPONSE_CODE%"
            response_flags: "%RESPONSE_FLAGS%"
            upstream_host: "%UPSTREAM_HOST%"
            upstream_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
            duration: "%DURATION%"
            request_id: "%REQ(X-REQUEST-ID)%"
            upstream_cluster: "%UPSTREAM_CLUSTER%"
# Envoy Response Flags 含义
# UH: 上游不健康(无可用后端)
# UF: 上游连接失败
# UO: 上游溢出(熔断器触发)
# UT: 上游请求超时
# LR: 本地重置(Envoy 重置连接)
# UR: 上游重置
# UC: 上游连接终止
# NR: 无路由匹配
# RL: 速率限制
# DC: 下游连接终止
# DPE: 下游协议错误

# 分析 Response Flags
cat /var/log/envoy/access.log | \
    jq -r '.response_flags' | sort | uniq -c | sort -rn

六、熔断与异常检测

6.1 Circuit Breaker

Envoy 的熔断器(Circuit Breaker)在集群级别工作,防止后端过载:

clusters:
  - name: api_cluster
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 1024       # 最大连接数
          max_pending_requests: 1024  # 等待连接的最大请求数
          max_requests: 1024          # 最大并发请求数
          max_retries: 3              # 最大并发重试数
          track_remaining: true       # 暴露剩余配额指标
# 监控熔断器状态
curl -s http://localhost:9901/stats | grep circuit_breakers
# cluster.api_cluster.circuit_breakers.default.cx_open: 0
# cluster.api_cluster.circuit_breakers.default.rq_open: 0
# cluster.api_cluster.circuit_breakers.default.cx_pool_open: 0
# cluster.api_cluster.circuit_breakers.default.remaining_cx: 1024
# cluster.api_cluster.circuit_breakers.default.remaining_rq: 1024

6.2 Outlier Detection

clusters:
  - name: api_cluster
    outlier_detection:
      consecutive_5xx: 5              # 连续 5 个 5xx 后驱逐
      interval: 10s                   # 检测间隔
      base_ejection_time: 30s         # 基础驱逐时间
      max_ejection_percent: 50        # 最大驱逐比例
      enforcing_consecutive_5xx: 100  # 执行比例(100%)
      success_rate_minimum_hosts: 3   # 成功率统计最小主机数
      success_rate_request_volume: 100 # 成功率统计最小请求数
      success_rate_stdev_factor: 1900 # 成功率偏差因子

七、Admin API

# Envoy Admin API 常用端点

# 服务器信息
curl http://localhost:9901/server_info | jq .

# 集群状态
curl http://localhost:9901/clusters
# 显示每个集群的所有端点及其健康状态

# 配置转储
curl http://localhost:9901/config_dump | jq .

# 日志级别动态调整
curl -X POST http://localhost:9901/logging?level=debug
curl -X POST http://localhost:9901/logging?upstream=trace

# 重置统计
curl -X POST http://localhost:9901/reset_counters

# 排水(准备关闭)
curl -X POST http://localhost:9901/drain_listeners

# 健康检查失败(从 LB 中摘除自己)
curl -X POST http://localhost:9901/healthcheck/fail

# 准备就绪检查
curl http://localhost:9901/ready
# 返回 200 = Envoy 就绪,返回 503 = 未就绪

八、总结

  1. Envoy 的核心创新是 xDS API 驱动的动态配置。传统代理需要 reload 配置文件,Envoy 通过 gRPC 流实时接收配置更新——Listener、路由、集群、端点、证书都可以动态变更,不中断任何连接。

  2. Filter Chain 提供了极致的可扩展性。从 L4 到 L7,所有功能都是 Filter。Wasm 扩展让你可以用 Rust/Go/C++ 编写自定义逻辑,在运行时热加载。

  3. per-Worker 线程模型实现了高性能和低延迟。几乎无锁的设计让每个 Worker 线程独立处理自己的连接,配置更新通过 TLS(Thread Local Storage)无锁分发。

  4. 热重启让二进制升级零停机。通过 Unix Domain Socket 传递 listen fd 和共享内存交换统计数据,新旧进程无缝切换。

  5. 可观测性是一等公民。内置的统计指标、分布式追踪、结构化日志让 Envoy 在微服务架构中提供了无与伦比的可见性。


参考文献


上一篇:HAProxy 工程:高级配置、ACL 与运维

下一篇:反向代理模式:TLS 终止、透传与重加密

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .