云原生技术17-从Nginx到Envoy:为什么大厂都在迁移?xDS协议 + WASM扩展:Envoy高级玩法实战 1、AI程序员系列文章2、AI面试系列文章3、AI编程系列文章目录开篇代理界的变形金刚Envoy架构全景Listener → Filter → Cluster → Endpoint核心功能拆解不止于代理xDS协议动态配置的魔法WASM扩展不写C也能玩扩展性能优化榨干每一滴算力实战代码从配置到运行文末三件套开篇代理界的变形金刚你是否遇到过传统代理配置复杂难维护、动态服务发现支持差、扩展能力不足只能改源码的局限Envoy是云原生时代的高性能代理被Istio、AWS App Mesh等广泛采用。本文将深入Envoy掌握其核心原理与高级用法。效率技巧Envoy最初由Lyft开发后来捐献给CNCF现在是继Kubernetes、Prometheus之后的第三大CNCF毕业项目。它的诞生就是为了解决微服务架构中的网络通信痛点。想象一下如果你的代理能像变形金刚一样——既能当HTTP代理又能做TCP转发还能动态加载配置、热更新扩展那该多爽Envoy就是这样一个变形金刚而且它还特别快——单核QPS 10万P99延迟不到1毫秒。Envoy架构全景Listener → Filter → Cluster → EndpointEnvoy的架构设计堪称教科书级别。理解这四个核心概念你就掌握了Envoy的精髓┌─────────────────────────────────────────────────────────────────┐ │ Envoy Proxy │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Listener │ │ Listener │ │ Listener │ ... │ │ │ :8080 │ │ :8443 │ │ :9901 │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Filter Chain │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ TLS │ → │ HTTP │ → │ Router │ → │ Rate │ │ │ │ │ │Inspector│ │Connection│ │ Filter │ │ Limit │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Cluster │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │Endpoint │ │Endpoint │ │Endpoint │ Load │ │ │ │ │ :8081 │ │ :8082 │ │ :8083 │ Balancing │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘1. Listener监听器Listener是Envoy的耳朵负责监听指定的端口和协议。每个Listener都有自己的配置可以独立设置TLS、过滤器链等。static_resources: listeners: - name: listener_http address: socket_address: address: 0.0.0.0 port_value: 80802. Filter过滤器Filter是Envoy的大脑处理所有进出的流量。Envoy采用链式过滤器设计请求会依次经过每个过滤器Network Filters处理原始字节流TCPHTTP Filters处理HTTP请求/响应Listener Filters在连接建立前执行如TLS检查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 http_filters: - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router3. Cluster集群Cluster是Envoy的通讯录定义了一组上游服务的Endpoint。Cluster负责负载均衡、健康检查、熔断等高级功能。clusters: - name: service_backend connect_timeout: 5s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_backend endpoints: - lb_endpoints: - endpoint: address: socket_address: address: backend1 port_value: 80814. Endpoint端点Endpoint是实际处理请求的后端服务实例。Envoy支持多种服务发现机制来动态获取Endpoint列表。⚠️避坑警告初学者常犯的错误是把Cluster和Endpoint搞混。记住Cluster是逻辑分组Endpoint是具体实例。一个Cluster可以包含多个EndpointEnvoy会自动做负载均衡。核心功能拆解不止于代理Envoy的核心功能可以用六边形战士来形容——每个方向都很能打1. HTTP/TCP代理Envoy同时支持L4TCP和L7HTTP代理# HTTP代理配置示例 static_resources: listeners: - name: http_listener address: socket_address: { address: 0.0.0.0, port_value: 80 } 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 codec_type: AUTO route_config: name: local_route virtual_hosts: - name: backend domains: [*] routes: - match: { prefix: / } route: { cluster: service_backend } http_filters: - name: envoy.filters.http.router2. 负载均衡策略Envoy支持多种负载均衡算法策略说明适用场景ROUND_ROBIN轮询后端性能均匀LEAST_REQUEST最少请求请求处理时间差异大RING_HASH一致性哈希需要会话保持RANDOM随机简单场景MAGLEVMaglev一致性哈希大规模集群clusters: - name: service_backend lb_policy: LEAST_REQUEST least_request_lb_config: choice_count: 2 # 二选一选请求数最少的3. 健康检查Envoy的健康检查机制非常完善clusters: - name: service_backend health_checks: - timeout: 5s interval: 10s unhealthy_threshold: 3 healthy_threshold: 2 http_health_check: path: /health expected_statuses: start: 200 end: 299效率技巧健康检查有主动Active和被动Outlier Detection两种。主动检查是Envoy定期ping后端被动检查是根据实际请求的成功率来判断。建议两者结合使用。4. 熔断Circuit Breaker熔断机制防止故障扩散就像电路中的保险丝clusters: - name: service_backend circuit_breakers: thresholds: - priority: DEFAULT max_connections: 1000 max_pending_requests: 1000 max_requests: 1000 max_retries: 3熔断触发条件连接数超过max_connections等待队列超过max_pending_requests并发请求超过max_requests重试次数超过max_retries5. 限流Rate LimitEnvoy支持本地限流和全局限流# 本地限流 - 每个Envoy实例独立计数 http_filters: - 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 filter_enabled: runtime_key: local_rate_limit_enabled default_value: numerator: 100 denominator: HUNDREDxDS协议动态配置的魔法如果说Envoy的静态配置是手动挡那xDS就是自动挡自动驾驶。xDS是一组发现服务的统称让Envoy能够动态获取配置无需重启。┌─────────────────────────────────────────────────────────────┐ │ xDS 协议全景 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ LDS │ │ RDS │ │ CDS │ │ EDS │ │ │ │Listener │ │ Route │ │ Cluster │ │ Endpoint │ │ │ │Discovery │ │Discovery │ │Discovery │ │Discovery │ │ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ │ │ └─────────────┴──────┬──────┴─────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ xDS Control │ │ │ │ Plane │ │ │ │ (Istiod/ │ │ │ │ Consul/ │ │ │ │ Custom) │ │ │ └────────┬────────┘ │ │ │ │ │ ┌──────────────┼──────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Envoy │ │ Envoy │ │ Envoy │ │ │ │ 实例1 │ │ 实例2 │ │ 实例N │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 其他xDS │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ SDS │ │ ADS │ │ RTDS │ │ │ │ Secret │ │Aggregated│ │ Runtime │ │ │ │Discovery │ │Discovery │ │Discovery │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘xDS协议详解协议全称作用典型场景LDSListener Discovery Service动态发现Listener配置新增/删除端口监听RDSRoute Discovery Service动态发现路由配置灰度发布、A/B测试CDSCluster Discovery Service动态发现Cluster配置新增/删除服务集群EDSEndpoint Discovery Service动态发现Endpoint列表服务扩缩容、故障转移SDSSecret Discovery Service动态发现TLS证书证书自动轮换ADSAggregated Discovery Service聚合所有xDS减少连接数、保证一致性xDS配置实战# 动态配置示例 - 连接到Istio控制平面 dynamic_resources: ads_config: api_type: GRPC transport_api_version: V3 grpc_services: - envoy_grpc: cluster_name: xds_cluster cds_config: resource_api_version: V3 ads: {} lds_config: resource_api_version: V3 ads: {} static_resources: clusters: - name: xds_cluster connect_timeout: 1s type: STRICT_DNS lb_policy: ROUND_ROBIN http2_protocol_options: {} load_assignment: cluster_name: xds_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: istiod.istio-system.svc.cluster.local port_value: 15012 transport_socket: name: envoy.transport_sockets.tls typed_config: type: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext common_tls_context: tls_certificate_sds_secret_configs: - name: default sds_config: path: /etc/istio-certs/cert-chain.pem validation_context_sds_secret_config: name: ROOTCA sds_config: path: /etc/istio-certs/root-cert.pem⚠️避坑警告使用xDS时一定要注意版本兼容性。Envoy 1.13 默认使用V3 API旧版控制平面可能不兼容。另外ADS虽然方便但所有配置变更都走一条gRPC连接一旦断开会影响所有资源类型。WASM扩展不写C也能玩扩展Envoy最强大的特性之一就是可扩展性。以前要写C编译进Envoy现在有了WASMWebAssembly你可以用Rust、C、AssemblyScript等语言写过滤器热更新无需重启┌─────────────────────────────────────────────────────────────┐ │ WASM 扩展架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Envoy Proxy │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ WASM Runtime (VM) │ │ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ │ │ WASM Filter │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ │ │ │ │ onRequest│ │onResponse│ │ │ │ │ │ │ │ │ │Headers │ │Headers │ │ │ │ │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ │ │ │ │ onRequest│ │onResponse│ │ │ │ │ │ │ │ │ │Body │ │Body │ │ │ │ │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ │ │ Host Functions │ │ │ │ │ │ │ │ (ABI Interface)│ │ │ │ │ │ │ └─────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 开发语言选项 │ │ • Rust (推荐) - envoy-wasm-sdk │ │ • C - proxy-wasm-cpp-sdk │ │ • AssemblyScript - 类TypeScript语法 │ │ • Go - tinygo编译器 │ │ │ └─────────────────────────────────────────────────────────────┘WASM过滤器实战Rust// 一个简单的WASM过滤器 - 添加自定义Header use proxy_wasm::traits::*; use proxy_wasm::types::*; proxy_wasm::main! {{ proxy_wasm::set_log_level(LogLevel::Trace); proxy_wasm::set_root_context(|_| - Boxdyn RootContext { Box::new(CustomRootContext) }); }} struct CustomRootContext; impl Context for CustomRootContext {} impl RootContext for CustomRootContext { fn get_type(self) - OptionContextType { Some(ContextType::HttpContext) } fn create_http_context(self, context_id: u32) - OptionBoxdyn HttpContext { Some(Box::new(CustomHttpContext { context_id })) } } struct CustomHttpContext { context_id: u32, } impl Context for CustomHttpContext {} impl HttpContext for CustomHttpContext { fn on_http_request_headers(mut self, _num_headers: usize, _end_of_stream: bool) - Action { // 添加自定义Header标记经过WASM处理 self.add_http_request_header(x-wasm-processed, true); self.add_http_request_header(x-envoy-version, 1.28); // 记录日志 log::info!(Request processed by WASM filter, context_id: {}, self.context_id); Action::Continue } fn on_http_response_headers(mut self, _num_headers: usize, _end_of_stream: bool) - Action { // 在响应头中添加处理时间 self.add_http_response_header(x-wasm-timestamp, format!({}, self.get_current_time())); Action::Continue } }Envoy配置加载WASMhttp_filters: - name: envoy.filters.http.wasm typed_config: type: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm config: name: custom_filter root_id: custom_filter_root vm_config: vm_id: custom_filter_vm runtime: envoy.wasm.runtime.v8 code: remote: http_uri: uri: http://wasm-registry/wasm/custom-filter.wasm cluster: wasm_registry timeout: 10s sha256: abc123... # 校验和确保完整性 configuration: type: type.googleapis.com/google.protobuf.StringValue value: | { header_name: x-custom-header, header_value: wasm-powered } - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router效率技巧WASM过滤器虽然强大但要注意性能开销。每个请求都要经过WASM VM建议1) 尽量在RootContext做初始化2) 避免在热路径分配内存3) 使用V8 runtime比WAVM更轻量。性能优化榨干每一滴算力Envoy本身就是为高性能设计的但正确的配置能让它飞得更快1. 连接池优化clusters: - name: service_backend connect_timeout: 5s # 连接池配置 common_http_protocol_options: idle_timeout: 300s # 空闲连接超时 upstream_connection_options: tcp_keepalive: keepalive_time: 300 keepalive_interval: 75 keepalive_probes: 9 # HTTP/2 配置 http2_protocol_options: hpack_table_size: 4096 max_concurrent_streams: 100 initial_stream_window_size: 65536 initial_connection_window_size: 655362. 线程模型优化Envoy采用每个线程一个事件循环的模型# 启动时指定工作线程数通常等于CPU核心数 envoy -c config.yaml --concurrency 8 # 或者设置为自动检测 envoy -c config.yaml --concurrency 0┌─────────────────────────────────────────────────────────────┐ │ Envoy 线程模型 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ │ │ │ Main Thread │ 配置加载、xDS通信、统计 │ │ └─────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Worker Threads (N CPU cores) │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Worker 0│ │ Worker 1│ │ Worker 2│ │ Worker N│ │ │ │ │ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │ │ │ │ │Event│ │ │ │Event│ │ │ │Event│ │ │ │Event│ │ │ │ │ │ │Loop │ │ │ │Loop │ │ │ │Loop │ │ │ │Loop │ │ │ │ │ │ └─────┘ │ │ └─────┘ │ │ └─────┘ │ │ └─────┘ │ │ │ │ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │ │ │ │ │Conn │ │ │ │Conn │ │ │ │Conn │ │ │ │Conn │ │ │ │ │ │ │Pool │ │ │ │Pool │ │ │ │Pool │ │ │ │Pool │ │ │ │ │ │ └─────┘ │ │ └─────┘ │ │ ├─────┤ │ │ └─────┘ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ 特点 │ │ │ │ • 每个Worker独立运行无锁竞争 │ │ │ │ • 连接一旦分配到Worker不会迁移 │ │ │ │ • SO_REUSEPORT实现内核级负载均衡 │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘3. 内存管理# 缓冲区配置 overload_manager: refresh_interval: 0.25s resource_monitors: - name: envoy.resource_monitors.fixed_heap typed_config: type: type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig max_heap_size_bytes: 2147483648 # 2GB actions: - name: envoy.overload_actions.shrink_heap triggers: - name: envoy.resource_monitors.fixed_heap threshold: value: 0.95 - name: envoy.overload_actions.stop_accepting_requests triggers: - name: envoy.resource_monitors.fixed_heap threshold: value: 0.99性能数据速览指标数值说明单核QPS10万HTTP/1.1长连接P99延迟 1ms本地测试无后端延迟内存占用~100MB/实例基础配置无大量路由连接数100万依赖ulimit和内核参数效率技巧Envoy的性能调优要关注三个层面1) 内核参数ulimit、net.core.somaxconn2) Envoy配置线程数、连接池、缓冲区3) 后端服务响应时间Envoy再快后端慢也是白搭。实战代码从配置到运行完整Envoy配置示例# envoy.yaml - 完整的反向代理配置 static_resources: listeners: - name: listener_0 address: socket_address: address: 0.0.0.0 port_value: 10000 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 access_log: - name: envoy.access_loggers.stdout typed_config: type: type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog log_format: text_format: [%START_TIME%] \%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\ %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \%REQ(X-FORWARDED-FOR)%\ \%REQ(USER-AGENT)%\ \%REQ(X-REQUEST-ID)%\ \%REQ(:AUTHORITY)%\ \%UPSTREAM_HOST%\\n route_config: name: local_route virtual_hosts: - name: backend domains: [*] routes: - match: prefix: /api/v1/ route: cluster: api_service timeout: 30s retry_policy: retry_on: 5xx,connect-failure num_retries: 3 per_try_timeout: 10s - match: prefix: / route: cluster: web_service timeout: 10s http_filters: - name: envoy.filters.http.cors typed_config: type: type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors - 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: 10000 tokens_per_fill: 1000 fill_interval: 1s filter_enabled: runtime_key: local_rate_limit_enabled default_value: numerator: 100 denominator: HUNDRED - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: api_service connect_timeout: 5s type: STRICT_DNS lb_policy: LEAST_REQUEST health_checks: - timeout: 3s interval: 10s unhealthy_threshold: 3 healthy_threshold: 2 http_health_check: path: /health circuit_breakers: thresholds: - priority: DEFAULT max_connections: 1000 max_pending_requests: 1000 max_requests: 1000 load_assignment: cluster_name: api_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: api port_value: 8080 - name: web_service connect_timeout: 5s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: web_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: web port_value: 80 admin: address: socket_address: address: 0.0.0.0 port_value: 9901Docker运行# 启动Envoy docker run -d \ --name envoy \ -p 10000:10000 \ -p 9901:9901 \ -v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml \ envoyproxy/envoy:v1.28.0 # 查看统计信息 curl http://localhost:9901/stats/prometheus # 查看配置 curl http://localhost:9901/config_dump性能测试# 使用wrk进行压测 wrk -t12 -c400 -d30s http://localhost:10000/ # 使用hey进行压测 hey -n 100000 -c 100 -m GET http://localhost:10000/文末三件套1. 【源码获取】关注此系列获取后续更新后台回复’envoy’获取本文完整配置文件和WASM示例代码。2. 【思考题】你们现在用什么代理是Nginx、HAProxy还是已经在用Envoy了欢迎在评论区分享你的经验和踩过的坑。3. 【系列预告】云原生网络系列持续更新中Linkerd→ 更轻量的服务网格选择多集群网格→ 跨集群服务治理实战混合云→ 私有云公有云的统一网络边缘计算→ Envoy在边缘场景的应用总结Envoy作为云原生时代的瑞士军刀代理凭借其出色的性能单核10万QPS、P991ms、灵活的架构Listener→Filter→Cluster→Endpoint和强大的扩展能力xDS动态配置、WASM热更新已经成为Istio、AWS App Mesh等主流服务网格的数据面标准。本文从架构原理到实战配置从xDS协议到WASM扩展全面解析了Envoy的核心能力。希望这篇文章能帮助你理解Envoy的设计理念- 为什么它能成为云原生代理的事实标准掌握核心配置方法- 能够独立搭建和调优Envoy代理了解高级特性- xDS动态配置和WASM扩展为你的架构提供更多可能性⚠️避坑警告Envoy功能强大配置也相对复杂。建议从静态配置开始逐步过渡到动态xDS生产环境务必开启健康检查和熔断保护WASM扩展虽好但要注意性能开销。标签Envoy, 代理, xDS, WASM, 负载均衡, 服务网格, 云原生网络参考链接Envoy官方文档Envoy GitHubIstio架构解析WASM扩展开发指南