Nginx反向代理实现灰度发布的核心是基于请求特征(Header、Cookie、IP)路由流量至新/旧版本服务,无需改业务代码;推荐用map、split_clients等指令替代if,结合OpenResty/Lua与动态配置提升灵活性和可靠性。

利用 Nginx 反向代理实现灰度发布,核心是让部分用户流量定向到新版本服务,其余仍走旧版本,无需修改业务代码,依赖请求特征(如 Header、Cookie、IP)做路由决策。
基于请求头(Header)的灰度路由
适合前端或网关层能主动携带灰度标识的场景,例如在测试时由 Postman 或前端脚本添加 X-Release: v2 请求头。
配置示例如下:
在 upstream 块中定义两套后端:
upstream backend-stable {
server 192.168.1.10:8080;
}
upstream backend-canary {
server 192.168.1.11:8080;
}
在 server 块中按 Header 分流:
location / {
if ($http_x_release = "v2") {
proxy_pass http://backend-canary;
break;
}
proxy_pass http://backend-stable;
}
注意:不建议在 location 中频繁使用 if,更稳妥的方式是用 map 指令提前映射变量:
map $http_x_release $upstream_backend {
"v2" "backend-canary";
default "backend-stable";
}
server {
location / {
proxy_pass http://$upstream_backend;
}
}
基于 Cookie 的用户级灰度
适用于需要对特定用户(如内部员工、灰度白名单)长期固定分配版本的场景。
- 提取 Cookie 中的 key(如 gray=1),用 map 匹配
- 配合 proxy_cookie_path 避免下游服务误读 Cookie
- 可结合 set_cookie 指令自动打标(需搭配 Lua 或 OpenResty 扩展)
基础配置示例:
map $cookie_gray $upstream_backend {
"1" "backend-canary";
default "backend-stable";
}
server {
location / {
proxy_pass http://$upstream_backend;
# 可选:隐藏灰度 Cookie,避免透传给后端
proxy_cookie_path / "/; Secure; HttpOnly";
}
}
基于客户端 IP 的比例/范围灰度
适合小流量验证,例如将 5% 的公网用户导流至新版本,或指定某网段(如公司办公 IP)全量灰度。
- 用 geo 指令预定义 IP 映射变量,性能优于运行时正则匹配
- 用 split_clients 实现哈希一致性分流(推荐用于比例灰度)
- 避免直接用 $remote_addr 判断,需考虑 CDN 或反代后的真实 IP(启用 real_ip 模块)
哈希分流示例(5% 用户命中 canary):
split_clients "${remote_addr}AAA" $upstream_backend {
5% "backend-canary";
* "backend-stable";
}
server {
location / {
proxy_pass http://$upstream_backend;
}
}
进阶:多维度组合与动态控制
单一维度易受干扰,生产环境建议叠加判断逻辑。Nginx 本身不支持复杂 if 嵌套,可通过以下方式增强灵活性:
- 用 map 多级嵌套(例如先 match Cookie,未命中再 fallback 到 IP 哈希)
- 借助 OpenResty + Lua,在 access_by_lua_block 中编写自定义策略(如查 Redis 白名单、调用鉴权接口)
- 配合 Consul 或 Nacos 实现上游服务的动态注册与权重调整,Nginx 通过 upstream_conf 或 stream 动态更新
- 记录灰度标识到日志(log_format 中加入 $upstream_backend 或 $cookie_gray),便于链路追踪和效果分析
不复杂但容易忽略:所有灰度配置上线前,务必在测试环境验证 header 传递、cookie 路径、IP 获取准确性,并检查 proxy_set_header 是否保留原始信息(如 Host、X-Real-IP)。


















