基于两台服务器的蓝绿切换实现零下线更新

55 阅读3分钟

一、概念

在网站或应用的运维中,“零下线更新”是指在发布新版本时,用户访问不受影响,不会出现中断、502 错误或服务不可达。常见的一种做法是 蓝绿部署(Blue-Green Deployment)

  • 蓝环境(Blue) :当前运行的生产版本,正在处理用户请求;
  • 绿环境(Green) :新版本环境,在后台完成更新与测试;
  • 切换:当绿环境稳定后,将流量从蓝环境切换到绿环境;如果发现问题,再快速切回蓝环境。

二、原理

  1. 两台服务器独立运行

    • 一台服务器作为现网服务;
    • 另一台空闲服务器用于新版本部署。
  2. Nginx 负载均衡控制流量

    • 在前端通过 upstream 管理两台服务器;
    • 切换时修改权重或启用/禁用某台服务器,reload Nginx 配置即可生效。
  3. 平滑切换机制

    • Nginx reload 是平滑的,不会直接杀掉旧进程;
    • 旧的 Worker 会等待当前请求处理完毕后再退出;
    • 新 Worker 会立即接管新请求,从而实现零停机。

三、对比

  • 单机热更新:通过软链切换或直接覆盖文件来更新,简单但风险高,一旦更新失败会影响整个服务。
  • 蓝绿部署:两台服务器互为备份,流量可随时切换,安全性更高,更新过程对用户透明。
  • 灰度发布:在蓝绿基础上进一步扩展,可逐步分配流量,验证稳定性后再全量切换。

四、实践

Nginx 配置示例

upstream backend {
    server 192.168.1.101:8080 weight=1;  # 蓝环境
    # server 192.168.1.102:8080 weight=0;  # 绿环境(未启用)
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
    }
}

切换流程

  1. 在蓝环境正常运行时,更新绿环境;

  2. 完成新版本部署和测试;

  3. 修改 upstream,把流量切到绿环境:

    upstream backend {
        # server 192.168.1.101:8080 weight=0;
        server 192.168.1.102:8080 weight=1;
    }
    
  4. nginx -t && nginx -s reload 平滑生效;

  5. 观察运行情况,如果有问题,立刻切回蓝环境。


五、拓展

  • 灰度流量分配:先给绿环境分配少量流量(如 10%),逐步放量;
  • 健康检查:在 Nginx 或上层负载均衡中增加健康检查,确保异常节点不接收请求;
  • 自动化部署:结合 CI/CD 工具,实现部署、切换、回滚一体化。

六、潜在问题与不足

  1. 成本问题

    • 至少需要两台服务器,资源利用率偏低;
    • 小型团队可能难以承担额外硬件开销。
  2. 会话保持问题

    • 如果应用依赖本地 Session,切换时可能导致用户登录状态丢失;
    • 通常需要外部存储(Redis、数据库)来做会话共享。
  3. 数据库版本兼容问题

    • 蓝绿服务器共用同一个数据库时,新旧版本可能对数据结构有不同要求;
    • 需要数据库向下兼容,或者提前做 schema 升级。
  4. 切换瞬间的请求不一致

    • 如果有长连接(WebSocket/HTTP2),可能部分连接仍然留在旧环境;
    • 需要在应用层设计容错机制。
  5. DNS 切换滞后(如果用 DNS 方式)

    • DNS 缓存会导致部分用户仍然访问旧环境,影响一致性。

七、总结

两台服务器的蓝绿切换方案,是实现 零下线更新 的经典方式,简单、可靠、回滚迅速。它特别适合对 服务可用性要求高 的业务场景。但在资源成本、会话保持、数据库兼容和长连接管理上仍有不足,需要结合 共享存储、灰度发布、自动化工具 才能做到真正的高可用与稳定。


本文部分内容借助 AI 辅助生成,并由作者整理审核。