灰度发布策略
灰度发布通过逐步切换流量验证新版本稳定性,降低全量发布风险。
权重分流
基础权重方案
nginx
upstream stable {
server 10.0.0.1:8080;
}
upstream canary {
server 10.0.0.2:8080;
}
server {
location / {
set $upstream "stable";
if ($request_uri ~* "canary=1") {
set $upstream "canary";
}
proxy_pass http://$upstream;
}
}
split_clients 模块
nginx
split_clients $remote_addr $canary {
5% canary;
* stable;
}
server {
location / {
if ($canary = "canary") {
proxy_pass http://canary_backend;
}
proxy_pass http://stable_backend;
}
}
split_clients 基于变量哈希值划分流量,支持百分比精确控制。
Header/Cookie 路由
Header 路由
nginx
map $http_x_canary $upstream_canary {
default stable;
"1" canary;
"true" canary;
}
server {
location / {
proxy_pass http://$upstream_canary;
proxy_set_header X-Upstream-Group $upstream_canary;
}
}
Cookie 路由
nginx
map $cookie_canary $upstream_cookie {
default stable;
"internal" canary;
}
server {
location / {
proxy_pass http://$upstream_cookie;
}
}
金丝雀发布
OpenResty 方案
lua
-- canary.lua
local function select_backend()
local headers = ngx.req.get_headers()
-- 内部员工流量
if headers["X-Canary"] == "internal" then
return "canary"
end
-- 按用户 ID 分流
local uid = ngx.var.cookie_user_id
if uid and tonumber(uid) % 100 < 10 then -- 10% 流量
return "canary"
end
return "stable"
end
local backend = select_backend()
ngx.var.backend = backend
配置实现
nginx
upstream stable {
server 10.0.0.1:8080 weight=90;
server 10.0.0.2:8080 weight=10; # 新版本
}
# 逐步调整权重
# 5% → 10% → 25% → 50% → 100%
动态配置更新
Nginx Plus API
Bash
# 动态调整权重
curl -X POST http://localhost:8080/api/7/http/upstreams/backend/peers/1 \
-d '{"weight": 25}'
# 动态添加服务器
curl -X POST http://localhost:8080/api/7/http/upstreams/backend/servers \
-d '{"server": "10.0.0.3:8080", "weight": 5}'
OpenResty 动态上游
lua
local balancer = require("ngx.balancer")
local function get_peer()
local redis = require("resty.redis")
local red = redis:new()
red:connect("127.0.0.1", 6379)
local canary_weight = red:get("canary:weight") or 5
local rand = math.random(100)
if rand < tonumber(canary_weight) then
return "10.0.0.2", 8080
else
return "10.0.0.1", 8080
end
end
balancer.set_current_peer(get_peer())
发布流程
标准灰度流程
text
阶段 1: 5% 流量(15分钟)
→ 监控错误率/延迟
→ 异常:回滚
阶段 2: 25% 流量(30分钟)
→ 监控业务指标
→ 异常:回滚
阶段 3: 50% 流量(1小时)
→ 全面验证
→ 异常:回滚
阶段 4: 100% 流量
→ 发布完成
→ 保留旧版本(可快速回滚)
自动化回滚条件
| 指标 | 阈值 | 动作 |
|---|---|---|
| 错误率 | > 5% | 立即回滚 |
| P99 延迟 | > 2x 基线 | 立即回滚 |
| 5xx 比例 | > 1% | 立即回滚 |
| 业务指标 | 下降 > 10% | 人工决策 |
要点总结
- 权重分流通过 upstream weight 控制流量比例,简单但需 reload
- split_clients 基于哈希划分流量,无需 reload 即可生效
- Header/Cookie 路由支持内部测试和用户定向
- 金丝雀发布逐步提升新版本权重,配合监控指标判断是否继续
- 动态配置通过 Nginx Plus API 或 OpenResty 实现零停机灰度
📝 发现内容有误?点击此处直接编辑