原生蓝绿:两套完整环境,流量一次性全部切换;风险点:一旦切过去,全部用户都走到新版本,故障爆炸半径是全站

蓝绿 + 灰度(组合模式):保留蓝、绿两套完整集群,不直接一次性全量切流,先给绿环境放小部分灰度流量,验证没问题,再逐步放大直到 100%;异常则直接把流量切回蓝环境,兼顾:新版本完整环境隔离 + 灰度小流量验证 + 秒级整体回滚能力。

一、基础概念回顾

蓝绿部署 Blue‑Green

  • 蓝环境:线上正在运行旧版本 V1,承接全部业务流量
  • 绿环境:独立一套同等规格集群,部署新版本 V2,初期0 流量
  • 传统蓝绿:验证绿环境正常,LB / 网关直接100% 流量切到绿;故障直接切回蓝环境;蓝环境保留,作为下次发布的备用环境

缺点:瞬间全量切换,如果新版本存在并发下隐藏 bug,全站受影响

灰度(金丝雀 Canary)

新旧版本同时接收流量,按权重 / 用户 / Header 逐步放量,先小流量验证,慢慢扩到全量;风险可控,但没有完整独立的旧集群,回滚需要缩容新版本实例。

蓝绿 + 灰度组合(生产高级模式)

核心两套完整集群做底座,网关做灰度流量权重控制,分阶段把流量从蓝集群导到绿集群,而不是一刀切换

二、完整工作流程(7 步)

  1. 现状:蓝集群(V1)承载 100% 线上流量;绿集群空闲。
  2. 部署新版本:在绿集群部署 V2,内部接口测试、预热,此时绿集群0 线上流量
  3. 开启灰度放量:网关 / Ingress/SLB 配置流量策略,例如:95% 流量→蓝 (V1),5% 流量→绿 (V2),真实生产小流量进入新版本集群。

    支持:按权重、用户 ID、请求 Header、地域做灰度规则。

  4. 观测指标:持续监控绿集群:错误率、响应时间、GC、线程堆栈、慢 SQL、业务日志;告警触发就终止发布。
  5. 逐步放大流量:无异常,逐步调权重:5% → 20% → 50% → 80% → 100%。
  6. 全量切换:100% 流量切至绿集群,此时蓝集群不再接收流量,但集群实例不销毁,保留待命
  7. 收尾:确认稳定运行一段时间后(数小时~1 天),蓝集群部署下一个新版本,变为下一轮的“绿环境”,循环。

故障回滚:任意阶段发现绿集群异常,网关直接把全部流量切回蓝集群(V1 完整集群),秒级恢复,不需要重建实例、不需要回滚部署。

三、架构实现方式

1)K8s 实现(主流)

  • deploy‑blue:标签 version:blue,运行 V1
  • deploy‑green:标签 version:green,运行 V2
  • Service 不直接绑定版本;依靠 Ingress‑Nginx / Istio 做流量权重分流,把部分流量打向 green,其余到 blue。

Istio 示例逻辑:虚拟服务配置权重

virtualservice:
  route:
    - destination: {host: svc, subset: blue}
      weight: 90
    - destination: {host: svc, subset: green}
      weight: 10

2)传统虚拟机 / 物理机(Nginx+SLB)

两套后端 upstream:upstream_blue(V1)、upstream_green(V2);
Nginx split_clients 或者 SLB 的流量权重,实现流量按比例分发两套集群。

split_clients "${remote_addr}" $canary {
    5%     upstream_green;
    *       upstream_blue;
}

四、组合模式优势(对比单纯蓝绿、单纯灰度)

  1. 风险比原生蓝绿小:不是瞬间全站切新版本,小流量先验证,避免一次性全站故障。
  2. 回滚能力强于普通灰度:一旦出事,直接切回完整蓝集群,不需要删除 / 缩容 pod,秒级整体回滚。普通灰度回滚需要关闭新版本实例。
  3. 环境完全隔离:新版本部署在独立绿集群,部署、预热、内部测试完全不影响线上旧集群。
  4. 支持精细化灰度:可以按用户、Header 做定向流量,不止简单百分比。

五、缺点

  1. 资源成本高,必须维护两套完整集群,资源几乎翻倍。普通灰度只需要少量新版本实例。
  2. 数据库 Schema 必须向前兼容:蓝、绿集群新旧版本同时读写 DB,表结构变更必须兼容新旧代码,否则报错。

六、和普通灰度(金丝雀)对比

对比项普通灰度 (金丝雀)蓝绿 + 灰度组合模式
集群资源共享一套集群,少量实例升级新版本两套完整独立集群,资源翻倍
流量切换逐步扩副本 / 调权重;新旧实例混在同一集群两套集群之间做权重灰度分流
回滚动作缩减新版本实例网关一键切回整套旧集群
故障爆炸半径小;但旧版本和新版本混部可控灰度;保留完整旧环境兜底
适用场景常规迭代、资源紧张重大版本、架构改造、核心交易系统

七、关键风险点(生产踩坑)

  1. 数据库兼容问题:新旧版本同时访问 DB,表结构变更必须向前兼容,不能做破坏性变更;否则蓝集群旧代码写数据,绿集群读报错,反之亦然。
  2. 会话、缓存一致性:如果本地缓存,两套集群缓存独立,需要关注会话、token、缓存逻辑。
  3. 资源成本:双倍 CPU / 内存、连接池,大集群成本很高。
  4. 监控两套集群:蓝、绿两套都要采集指标、日志,不能只看新版本。

八、三种发布模式选型建议

  1. 普通迭代,资源有限普通灰度(金丝雀)
  2. 重大版本、架构重构、核心交易、想要秒级整体回滚蓝绿 + 灰度组合模式
  3. 简单小版本,追求发布速度,能接受瞬间切换风险原生蓝绿发布(直接一次性切 100% 流量)

九、故障处理操作

  1. 绿集群出现异常直接把流量权重全部切回 blue,不用删除 green 集群,快速恢复业务。
  2. 排查绿集群问题(GC、线程 dump、堆 dump、日志),修复后重新灰度发布。
  3. 不解决完问题,绝不把流量再切回绿集群

面试记忆点:蓝绿 + 灰度 = 蓝绿的完整双集群底座 + 灰度的分阶段流量放量,解决原生蓝绿“一次性全量切换风险大”的痛点

更多推荐