Nginx可通过proxy_pass结合变量、map、split_clients等指令,基于Header、Cookie、IP或权重实现轻量级灰度发布;推荐用map替代if做条件映射,配合预定义upstream和动态路由,确保安全可靠。

Nginx 本身不内置灰度发布能力,但可通过 proxy_pass 结合变量、请求头、Cookie、IP 等条件,配合 upstream 动态路由,实现轻量级的灰度流量切分。关键在于:用变量控制目标后端,让 proxy_pass 指向动态解析的 upstream 名或地址。
1. 基于请求头(如 X-Release)做静态灰度路由
适合人工触发灰度(如测试人员加 header 访问新版本):
- 在
upstream块中定义两组服务:
upstream backend-stable { server 10.0.1.10:8080; }
upstream backend-canary { server 10.0.1.20:8080; } - 在
location中通过$http_x_release判断并设置变量:
set $backend "backend-stable";
if ($http_x_release = "canary") { set $backend "backend-canary"; } - 使用变量拼接
proxy_pass(注意:必须用resolver+ 变量形式,或改用map更安全):
proxy_pass http://$backend;(需配合resolver,见下文说明)
2. 用 map 模块实现更健壮的条件映射
推荐方式,避免 if 在 location 中的限制和潜在问题:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 在
http块顶部定义映射规则:
map $http_x_release $upstream_backend {
default "backend-stable";
"canary" "backend-canary";
"v2" "backend-canary";
} - 在 location 中直接引用:
proxy_pass http://$upstream_backend; - 若需支持按 Cookie 或用户 ID 哈希分流(如固定用户走灰度),可结合
map+geo或split_clients(见第3点)
3. 按比例随机/哈希分流(A/B 测试式灰度)
适合渐进式放量,例如 5% 流量到新版本:
- 使用
split_clients模块生成确定性分流变量:
split_clients "${remote_addr}AAA" $canary_upstream {
5% "backend-canary";
* "backend-stable";
} - 该模块基于 MD5 哈希,相同客户端 IP 总是命中同一组,保证会话一致性
- 也可用
$cookie_uid或$arg_abtest_id替代$remote_addr,实现用户粒度控制
4. 注意事项与必要配置
动态 proxy_pass 必须满足以下任一条件,否则 Nginx 启动失败或无法解析变量:
-
启用 resolver(DNS 解析):如果 upstream 名是域名(如
backend-canary.example.com),需配置 DNS 解析器:
resolver 114.114.114.114 valid=30s;(放在 http/server/location 均可) -
避免使用域名,改用 IP+端口变量:更简单可靠,例如
set $upstream_host "10.0.1.20";
set $upstream_port "8080";
proxy_pass http://$upstream_host:$upstream_port; - 所有 upstream 必须预先定义(即使只在变量中引用),否则运行时报错 “no resolver defined” 或 “unknown upstream”
- 建议开启
proxy_next_upstream和健康检查,提升灰度期间容错能力

















