Envoy 代理负载均衡配置
FreeGuideOnline
最新
2026-07-01
yaml static_resources: listeners:
- name: listener_0
address: {...}
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager typed_config: ... route_config: name: local_route virtual_hosts: - name: backend domains: ["*"] routes: - match: { prefix: "/" } route: { cluster: service_cluster } clusters:
- filters:
- name: service_cluster
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_cluster
endpoints:
- lb_endpoints:
- endpoint: address: socket_address: address: backend1.example.com port_value: 80
- endpoint: address: socket_address: address: backend2.example.com port_value: 80
- lb_endpoints:
目前先记住:负载均衡策略定义在 `clusters` 段中,由 `lb_policy` 字段指定。
## 负载均衡策略配置
### 支持的策略一览
Envoy 为集群提供了多种开箱即用的负载均衡策略,可通过 `lb_policy` 字段进行设置:
| 策略名称 | 说明 |
| :--- | :--- |
| `ROUND_ROBIN` | 轮询,依次将请求分发到每个健康的主机。 |
| `LEAST_REQUEST` | 最少请求,选择活跃请求数最少的主机。 |
| `RING_HASH` | 一致性哈希,根据请求的某个属性(如 URL、头部)进行哈希,相同哈希的请求始终发往同一主机。 |
| `RANDOM` | 随机,从健康主机中随机选择。 |
| `MAGLEV` | Maglev 散列算法,提供比一致性哈希更均匀的负载分布,适合大规模集群。 |
| `CLUSTER_PROVIDED` | 从外部负载均衡器获取分配结果,通常用于对外服务发现提供支持。 |
### 策略选择建议
- **一般无状态服务**:`ROUND_ROBIN` 或 `LEAST_REQUEST` 是最常用的选择。`LEAST_REQUEST` 在服务处理时间差异较大时能更好地均衡负载。
- **需要会话保持或缓存亲和性**:使用 `RING_HASH` 或 `MAGLEV`,并基于特定 HTTP 头部(如 `x-user-id`)或 Cookie 进行哈希。
- **快速原型测试**:`RANDOM` 足够简单。
### 配置 ROUND_ROBIN
这是默认策略,即使不显式指定,Envoy 也采用轮询。示例:
```yaml
clusters:
- name: backend_rd
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: backend_rd
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 10.0.0.10
port_value: 8080
- endpoint:
address:
socket_address:
address: 10.0.0.11
port_value: 8080
配置 LEAST_REQUEST
clusters:
- name: backend_lr
type: STRICT_DNS
lb_policy: LEAST_REQUEST
# active_request_bias 可选,默认为1.0,值越大越倾向于选择并发请求最少的主机
least_request_config:
choice_count: 2 # 从2台随机选出,再在这2台中选并发请求最少的,避免所有请求都涌向完全空闲的节点
load_assignment:
...
配置 RING_HASH 实现会话保持
此策略通常需要定义 hash_policy。例如根据 x-session-id 头部进行哈希:
clusters:
- name: backend_rh
type: STRICT_DNS
lb_policy: RING_HASH
ring_hash_config:
minimum_ring_size: 1024
load_assignment:
cluster_name: backend_rh
endpoints: ...
在路由配置的 route 部分添加 hash_policy:
routes:
- match: { prefix: "/" }
route:
cluster: backend_rh
hash_policy:
- header:
header_name: "x-session-id"
如果需要更精细的控制,还可以基于 Cookie、连接属性或查询参数进行哈希。
健康检查配置
仅有负载均衡策略无法保证可靠性,必须为上游集群配置主动健康检查,以便及时剔除故障节点。
添加 HTTP 健康检查
clusters:
- name: backend_hc
type: STRICT_DNS
lb_policy: ROUND_ROBIN
health_checks:
- timeout: 2s
interval: 5s
unhealthy_threshold: 2
healthy_threshold: 2
http_health_check:
path: "/health"
expected_statuses:
- start: 200
end: 299
load_assignment:
cluster_name: backend_hc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: backend1
port_value: 8080
关键字段:
interval:健康检查间隔。unhealthy_threshold:连续失败多少次后标记为不健康。healthy_threshold:连续成功多少次后标记为健康(可用于主机启动预热)。timeout:每次检查的超时时间。
被动健康检查
Envoy 还支持被动健康检查,通过 outlier_detection 基于连续故障(如 5xx 错误、连接错误)自动瞬时踢出异常主机:
clusters:
- name: backend_od
...
outlier_detection:
consecutive_5xx: 3
interval: 10s
base_ejection_time: 30s
max_ejection_percent: 50
此功能不需要主动探测端点,可以大幅降低故障恢复正常前的失败请求数。
高级负载均衡特性
区域感知路由
当服务部署在多个可用区时,优先将请求路由到本可用区的后端,以减少跨区延迟和成本:
clusters:
- name: backend_zone
...
lb_policy: ROUND_ROBIN
common_lb_config:
locality_weighted_lb_config: {} # 启用区域加权
load_assignment:
cluster_name: backend_zone
endpoints:
- locality:
region: us-west
zone: zone1
lb_endpoints: [...]
- locality:
region: us-west
zone: zone2
lb_endpoints: [...]
当本区域端点全部不健康时,会向其他区域弹跳。
熔断器
防止单集群过载导致雪崩:
clusters:
- name: backend_cb
...
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 1000
max_pending_requests: 500
max_requests: 2000
max_retries: 3
重试策略
在路由层面配置重试,需谨慎与负载均衡配合:
routes:
- match: { prefix: "/" }
route:
cluster: backend_retry
retry_policy:
retry_on: "5xx,gateway-error,connect-failure"
num_retries: 2
per_try_timeout: 5s
完整配置实例与测试
场景说明
假设我们有两个后端服务 httpbin.org(模拟为本地 backend-1 和 backend-2),Envoy 边缘代理将流量以最少请求策略分发,并开启健康检查。
完整 Envoy 配置(static_resources 模式)
static_resources:
listeners:
- name: main_listener
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
route_config:
name: proxy_route
virtual_hosts:
- name: all
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: my_backend_cluster
http_filters:
- name: envoy.filters.http.router
clusters:
- name: my_backend_cluster
type: STRICT_DNS
lb_policy: LEAST_REQUEST
health_checks:
- timeout: 1s
interval: 10s
unhealthy_threshold: 2
healthy_threshold: 1
http_health_check:
path: "/get"
load_assignment:
cluster_name: my_backend_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: httpbin.org
port_value: 80
- endpoint:
address:
socket_address:
address: eu.httpbin.org
port_value: 80
启动并验证
- 将上述配置保存为
envoy-demo.yaml。 - 使用 Docker 启动 Envoy:
docker run -d --name envoy-lb -v $(pwd)/envoy-demo.yaml:/etc/envoy/envoy.yaml -p 10000:10000 envoyproxy/envoy:v1.28-latest - 发起多次请求,观察负载均衡效果(可查看响应中的 origin 字段区分不同后端):
for i in {1..6}; do curl -s http://localhost:10000/get | jq .origin; done - 通过 Envoy 管理接口查看集群状态和端点健康情况:
curl -s http://localhost:10000/clusters | jq .