Envoy Proxy 是一款开源、高性能的边缘代理与服务代理,专为云原生应用设计,在微服务架构中充当通用数据平面。它屏蔽了网络层的复杂性,提供分布式系统所必需的高级流量管理、可观测性与安全能力。
Envoy 作为服务间全部网络流量的透明代理运行,使开发者和运维人员可以专注于应用逻辑,而不必操心网络细节。其架构面向现代微服务部署构建,提供了传统代理往往不具备、或实现效率较低的特性。
核心架构原则
Envoy 的设计优先考虑性能、可扩展性和动态配置。它以单进程、多线程服务器的形式运行,利用事件驱动 I/O 高效处理大量并发连接和请求。
L3/L4 过滤器架构
Envoy 在网络层(L3/L4)和应用层(L7)都采用可插拔的过滤器链架构,从而实现高度可定制的网络流量处理。
* 网络过滤器: 作用于原始字节流。例如 TCP proxy、TLS 终止以及连接级别的限流。
* HTTP 过滤器: 作用于 HTTP 请求和响应。例如 Gzip 压缩、request ID 注入、JWT 认证和高级路由。
这种模块化设计使得在请求生命周期的各个阶段都能执行复杂的策略控制和流量改写。
面向微服务的关键特性
HTTP/2 与 gRPC 支持
Envoy 对现代微服务中的关键协议 HTTP/2 和 gRPC 提供一流支持。它可以把 HTTP/1.1 客户端桥接到 HTTP/2 服务、终止 HTTP/2 连接,并支持 gRPC 代理,包括感知 gRPC 的负载均衡和路由等高级特性。
高级负载均衡
除简单的轮询(round-robin)之外,Envoy 还提供一整套成熟的负载均衡算法:
* Least Request: 将请求路由到活跃请求数最少的后端。
* Ring Hash: 一致性哈希,提升缓存命中率并支持粘性会话。
* Maglev(Power of Two Choices): 随机挑选两个主机,选择其中活跃请求较少的一个,在简单性与近乎最优的分布之间取得平衡。
* Random: 用于简单、无偏的分配。
* Original Destination: 无需服务发现,直接路由到目标 IP。
它还支持自动重试、熔断(circuit breaking)、异常点检测(outlier detection)和健康检查,确保流量只发送到健康实例,从而提升系统韧性。
动态配置(xDS API)
Envoy 云原生设计的基石之一,是通过 xDS(Discovery Service)API 实现的动态配置能力。Envoy 不依赖静态配置文件,而是可以动态接收各类资源的更新:
* Listener Discovery Service(LDS): 监听器(Envoy 绑定的端口)。
* Route Discovery Service(RDS): HTTP 路由规则。
* Cluster Discovery Service(CDS): 上游集群(后端服务分组)。
* Endpoint Discovery Service(EDS): 集群内的端点(单个实例)。
* Secret Discovery Service(SDS): TLS 证书与私钥。
* Runtime Discovery Service(RTDS): 动态运行时配置值。
这使得配置变更可以零停机完成,支持持续交付,并可与管理这些配置的服务网格控制平面(例如 Istio、App Mesh)集成。
可观测性
Envoy 在设计上把可观测性作为一等公民,提供对网络流量的深入洞察:
* 详细统计指标: 输出大量统计数据(每个上游集群超过 100 项),涵盖连接、请求、错误、延迟等,可由 Prometheus 或类似系统抓取。
* 分布式链路追踪: 支持 Jaeger、Zipkin、AWS X-Ray 等主流追踪系统,传递追踪上下文(例如 B3、W3C Trace Context),并为每一跳生成 span。
* 访问日志: 全面且可自定义的访问日志,记录每个请求的详细信息,包括请求头、响应码和耗时。
这些特性对调试、性能分析以及分布式微服务的监控至关重要。
安全特性
Envoy 提供强大的安全能力,通常可把这些职责从应用代码中剥离:
* TLS 终止与发起: 处理 TLS 加解密,使服务内部可以用明文通信,同时保持对外通信安全。
* 双向 TLS(mTLS): 通过校验客户端证书,实现网格内服务之间安全且经过认证的通信。
* 限流: 施加请求速率限制,保护服务免受过载或滥用。
* 认证与授权: 通过 External Authorization 过滤器与外部授权服务(例如 OPA)集成,实现细粒度访问控制。
Envoy 在微服务架构中的角色
Sidecar 代理
在微服务环境中,Envoy 最常见的部署模式是 sidecar 代理。在该模型中,每个服务实例旁边都运行一个 Envoy 代理,在 Kubernetes 中通常位于同一个 pod 内。该服务的所有入站与出站网络流量都由 sidecar 透明拦截并管理。
这种方式带来若干好处:
* 网络抽象: 应用开发者编写的服务只与 localhost 通信,路由、重试等网络细节由 Envoy sidecar 处理。
* 多语言支持: 让使用不同语言和框架编写的服务拥有一致的网络策略与能力。
* 隔离: 网络关注点与业务逻辑分离,简化开发与部署。
服务网格数据平面
Envoy 是许多主流服务网格实现(例如 Istio、Linkerd、AWS App Mesh)事实上的数据平面。在服务网格中,控制平面管理并配置一整组 Envoy 代理(即数据平面)。控制平面通过 xDS API 动态更新网格内所有 Envoy 的配置,在整个微服务生态中统一实施流量策略、安全与可观测性。
边缘代理 / API 网关
Envoy 也可以部署在网络边缘,作为 API 网关或反向代理。在这一角色中,它负责处理入口流量,执行认证、限流和 TLS 终止,并把请求路由到微服务架构中相应的后端服务。其高级 L7 路由能力使它能够胜任复杂的边缘路由需求。
配置示例
一份基础的 Envoy 配置需要定义监听器、过滤器链和集群。下面的示例展示了一个监听 10000 端口的监听器,它把 HTTP 请求代理到名为 web_service 的上游服务集群。
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
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
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: web_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: web_service
connect_timeout: 0.25s
type: LOGICAL_DNS
# 如需在 v6 上测试,请注释掉下面这一行。
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: web_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: webserver.example.com # 替换为您实际的服务主机名/IP
port_value: 80
与其他代理的对比
| 特性 | Envoy Proxy | Nginx | HAProxy |
|---|---|---|---|
| 主要用途 | 服务网格、sidecar、API 网关、边缘 | Web 服务器、反向代理、负载均衡器 | 高性能 L4 负载均衡器,兼顾 L7 |
| 架构 | 事件驱动,C++,高度模块化的过滤器 | 事件驱动,C,基于模块 | 事件驱动,C,高度优化 |
| 动态配置 | 面向全部资源的完整 xDS API | 重载配置(有中断)或商业版 API | 有限变更的运行时 API,配置重载 |
| HTTP/2 与 gRPC | 一流支持,特性丰富 | 支持良好 | 支持良好 |
| 可观测性 | 丰富的指标、追踪与访问日志 | 基础指标,追踪能力有限 | 统计详尽,日志较基础 |
| 负载均衡 | 高级 L7(一致性哈希、Maglev)与 L4 | 基础 L7(round-robin、least conn)与 L4 | 高级 L4,部分 L7(least conn、source) |
| 服务发现 | 集成 xDS、DNS、静态配置 | DNS、静态配置、部分商业集成 | DNS、静态配置、部分商业集成 |
| 熔断 | 支持 | 不支持(需外部逻辑) | 支持 |
| 异常点检测 | 支持 | 不支持(需外部逻辑) | 不支持(需外部逻辑) |
| 服务网格角色 | 数据平面(首选) | 并非为此角色设计 | 并非为此角色设计 |
| 可扩展性 | C++ 过滤器、WASM 扩展 | Lua 脚本、C 模块 | Lua 脚本、C 模块 |
实践注意事项
性能调优
Envoy 开箱即用即具备很高性能,但特定部署仍可从调优中获益。主要方向包括:
* 线程配置: 调整 worker 线程数量以匹配 CPU 核心数。
* 缓冲区管理: 优化读/写缓冲区大小。
* 连接池规模: 配置到上游集群的最大连接数以及每连接的最大请求数。
资源消耗
尽管 Envoy 本身高效,但为每个服务实例都运行一个 Envoy sidecar 会增加整体资源消耗(CPU、内存)。考虑到服务网格带来的运维收益,这一取舍通常是可以接受的。在大规模部署中,仔细监控资源使用情况至关重要。
调试
Envoy 提供一个管理接口(通常在 15000 端口),其中包含多个实用的调试端点:
* /stats:当前统计数据。
* /config_dump:导出当前生效的配置。
* /clusters:上游集群状态。
* /hot_restart:发起一次平滑热重启。
这些端点对于排查配置问题、监控健康状况和理解流量走向都非常有用。
