全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-20 9 分钟 ✍️ juanwangdev

灰度发布策略

灰度发布通过逐步切换流量验证新版本稳定性,降低全量发布风险。

权重分流

基础权重方案

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 实现零停机灰度

📝 发现内容有误?点击此处直接编辑

← 上一篇 流量控制与限流
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库