nginx蓝绿部署核心是同upstream内用weight动态分流,如蓝v1 weight=90、绿v2 weight=10,配合健康检查、backup标记、curl探活、access日志观测及nginx -s reload热重载实现秒级无感切换。

用 Nginx 实现蓝绿部署,核心不是“非此即彼”的硬切换,而是通过 upstream 中的 weight 参数动态调节蓝、绿两个后端的流量比例,让版本过渡更可控、风险更低。它不需要改代码、不中断连接,reload 一下就生效,适合中小规模系统快速落地。
定义统一 upstream,蓝绿共存于同一分组
别把蓝和绿拆成两个完全隔离的 upstream,那样只能做“全量切换”。真正支持渐进发布的做法,是把它们放进同一个 upstream 块里,靠 weight 控制每台服务器承接多少请求:
- 蓝版(v1)设为 weight=90,承担 90% 流量
- 绿版(v2)设为 weight=10,先跑 10% 灰度流量
- 两台服务必须监听不同地址或端口,比如 192.168.1.10:8080 和 192.168.1.11:8080
配置示例:
upstream backend {
server 192.168.1.10:8080 weight=90; # 蓝
server 192.168.1.11:8080 weight=10; # 绿
}
权重调整要配合健康检查与平滑下线
只调 weight 不够,得确保新版本真的扛得住。Nginx 自带健康检查能力,建议开启:
- 加上 max_fails=3 fail_timeout=30s,连续失败 3 次就暂时剔除节点
- 绿版上线初期,可加 backup 标记,让它只在蓝版全挂时才启用(适合保守验证)
- 正式切流前,用 curl 测试绿版 /health 接口,确认返回 200 且响应时间正常
- 切完权重后,盯 5 分钟 access 日志,看绿版是否真有请求进来、错误率有没有突增
通过 reload 实现秒级生效,无需重启进程
修改完 weight 后,不能直接 kill 或 restart Nginx,要用热重载:
- 执行 nginx -t 校验配置语法是否正确
- 再执行 nginx -s reload,旧 worker 进程继续处理已有连接,新 worker 加载新配置并接管新请求
- 整个过程毫秒级完成,用户无感知
- 建议写个简单脚本封装这两步,避免手误漏掉 -t 导致服务中断
进阶:结合 map 实现按需路由+权重双控
如果既要灰度放量,又要支持特定人群(如内测用户、指定 Header)直连绿版,可以叠加 map:
- 用 map $http_x_test_user $route_to_green 判断请求头
- 在 location 中根据 $route_to_green 变量决定 proxy_pass 目标是 backend_green 还是统一 upstream
- 这样既能全局按权重分流,又能给测试人员开“绿色通道”,互不干扰











