技术深度剖析
Envoy 的架构从根本上不同于 NGINX 或 HAProxy 等传统代理。它从头开始就被设计为一个自包含、高性能的进程,通过 xDS API(发现服务)与控制平面通信。这种数据平面(Envoy)与控制平面(例如 Istio、Consul Connect)的分离是其定义性特征,实现了无需重启的动态运行时配置。
核心架构组件:
1. Listener: Envoy 在指定的 IP/端口上打开一个监听器。每个监听器可以有一个过滤器插件链来处理传入流量。
2. Filter Chain: 这是 Envoy 可扩展性的核心。过滤器可以是 L3/L4(例如 TCP 代理、TLS 终止)或 L7(例如 HTTP 连接管理器、gRPC-Web、速率限制)。过滤器可以堆叠,并能修改或重定向流量。例如,HTTP 连接管理器过滤器会进一步分解为 HTTP 级别的过滤器,如路由器、故障注入和 CORS。
3. Cluster: Envoy 可以路由流量到的一组上游主机。Envoy 支持复杂的负载均衡算法:加权轮询、最少请求、环哈希(一致性哈希)、maglev 和随机。它还实现了主动和被动健康检查、熔断和异常点检测。
4. xDS APIs: 控制平面使用这些 API 动态地向 Envoy 实例推送配置更新。关键的 API 包括:
* LDS(监听器发现服务): 配置监听器。
* RDS(路由发现服务): 配置路由规则。
* CDS(集群发现服务): 配置上游集群。
* EDS(端点发现服务): 配置集群内的端点。
* SDS(密钥发现服务): 管理 TLS 证书。
性能与基准测试:
Envoy 使用 C++11 编写,这使其在性能上优于 Traefik 或 Caddy 等基于 Go 的代理。其基于事件驱动、非阻塞 I/O 模型(基于 libevent)使其每个工作线程能够处理数万个连接。下表比较了在典型的 Sidecar 代理场景(1KB 请求,100 个并发连接)中 Envoy 与主要竞争对手的性能:
| 代理 | 吞吐量 (req/s) | P99 延迟 (ms) | 内存 (MB) | CPU 核心数 |
|---|---|---|---|---|
| Envoy 1.28 | 85,000 | 2.1 | 45 | 2 |
| NGINX 1.25 | 72,000 | 3.0 | 38 | 2 |
| HAProxy 2.8 | 90,000 | 1.8 | 52 | 2 |
| Traefik v3 | 55,000 | 4.5 | 68 | 2 |
*数据要点:Envoy 处于一个强劲的中间地带——它在原始吞吐量上落后于 HAProxy,但提供了显著更多的功能(L7 过滤、动态配置、可观测性),且没有基于 Go 的代理的内存开销。其 P99 延迟表现出色,使其非常适合对延迟敏感的微服务。*
关键 GitHub 仓库:
* envoyproxy/envoy (28,260 stars): 核心 C++ 代理。最近的提交集中在 HTTP/3 (QUIC) 支持、改进的 WASM 过滤器性能以及增强的访问日志格式化。
* envoyproxy/envoy-perf (1,200 stars): 一个专门用于性能回归测试和基准测试的仓库,对于维持其生产就绪状态至关重要。
* istio/istio (36,000 stars): 最流行的 Envoy 控制平面,增加了服务网格能力,如 mTLS、授权策略和流量转移。
关键参与者与案例研究
主要采用者及其用例:
* Lyft: 原始创建者。他们将 Envoy 用作所有微服务间东西向流量的通用数据平面,取代了自定义的基于 Ruby 的代理。这使延迟降低了 40%,并实现了金丝雀部署的细粒度流量转移。
* Netflix: 将 Envoy 用作边缘代理(Zuul 替代品)及其服务网格内部。他们贡献了 `envoy-mobile` 库,用于移动设备上的客户端负载均衡。
* Airbnb: 在边缘和服务网格流量中都使用了 Envoy。他们构建了一个名为 `Envoy Gateway` 的自定义控制平面,用于管理跨多个区域的数千个 Envoy 实例。
* Uber: 在其服务网格中重度使用 Envoy,利用其高级负载均衡(例如,带慢启动的最少请求)来处理大规模的打车流量峰值。
竞争格局:
| 产品 | 类型 | 配置 | 控制平面 | 关键优势 | 关键劣势 |
|---|---|---|---|---|---|
| Envoy | L7 代理 / 数据平面 | xDS API(动态) | 外部(Istio 等) | 可扩展性、可观测性、性能 | 设置复杂,学习曲线陡峭 |
| NGINX | L7 代理 / Web 服务器 | 静态文件 (nginx.conf) | 内置(有限) | 成熟度、简单性、庞大生态系统 | 动态性较差,难以与服务网格集成 |
| HAProxy | L4/L7 代理 | 静态文件 (haproxy.cfg) | 内置(有限) | 原始吞吐量、稳定性 | L7 功能有限,无原生服务网格 |
| Traefik | L7 反向代理 | 动态(K8s CRDs 等) | 内置 | 自动发现,易于 K8s 集成 |