目标
用 Envoy 搭建反向代理,实现流量分割(金丝雀发布):90% 流量到 v1,10% 到 v2。演示 L7 路由、加权分流的完整配置。
完整代码
架构
Browser → Envoy(:10000) ──90%──→ backend-v1(:8081)
──10%──→ backend-v2(:8082)
1. 后端服务 v1(Python)
# backend_v1.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import os
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"version":"v1","message":"This is stable version"}')
HTTPServer(("0.0.0.0", 8081), Handler).serve_forever()
2. 后端服务 v2(Python)
# backend_v2.py
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"version":"v2","message":"This is canary version"}')
HTTPServer(("0.0.0.0", 8082), Handler).serve_forever()
3. Envoy 配置(envoy-canary.yaml)
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
route_config:
name: canary_routes
virtual_hosts:
- name: app
domains: ["*"]
routes:
- match: { path: "/health" }
route:
cluster: backend_v1
- match: { prefix: "/" }
route:
weighted_clusters:
clusters:
- name: backend_v1
weight: 90
- name: backend_v2
weight: 10
total_weight: 100
retry_policy:
retry_on: "5xx"
num_retries: 2
per_try_timeout: 1s
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: backend_v1
type: STRICT_DNS
connect_timeout: 2s
load_assignment:
cluster_name: backend_v1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 127.0.0.1, port_value: 8081 }
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 100
max_pending_requests: 100
max_requests: 100
max_retries: 10
health_checks:
- timeout: 1s
interval: 5s
unhealthy_threshold: 3
healthy_threshold: 1
http_health_check:
path: "/health"
- name: backend_v2
type: STRICT_DNS
connect_timeout: 2s
load_assignment:
cluster_name: backend_v2
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 127.0.0.1, port_value: 8082 }
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 100
max_pending_requests: 100
max_requests: 100
max_retries: 10
4. 管理接口配置
admin:
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
运行步骤
python backend_v1.py &
python backend_v2.py &
envoy -c envoy-canary.yaml
for i in {1..20}
curl http:
curl http:
curl http:
curl http:
预期输出
$ for i in {1..20}
18 {"version":"v1","message":"This is stable version"}
2 {"version":"v2","message":"This is canary version"}
$ curl http:
关键点
weighted_clusters 实现加权流量分割,零代码金丝雀发布
retry_policy 配置自动重试,retry_on: 5xx 只在服务端错误时重试
circuit_breakers 防止连接池耗尽
health_checks 自动剔除不健康实例
- Admin 接口提供运行时诊断能力