蓝绿 + 灰度(虚拟机/物理机)

发布时间:2026/8/24 14:51:00
蓝绿 + 灰度(虚拟机/物理机) 架构概述采用WAF 前置 Nginx 流量分发的双层架构部署两套完整的业务集群蓝集群旧版本 V1和绿集群新版本 V2。WAFWeb 应用防火墙接收外部公网流量负责安全防护并将请求透传给后端 Nginx。注意WAF 不处理复杂的灰度逻辑仅透传请求头不做权重分流。Nginx网关层实现灰度分流、权重分配和流量切换后端配置两组 upstreamupstream_blue和upstream_green。核心区别传统蓝绿发布是直接 100% 切换流量而蓝绿 灰度发布则是通过 Nginx 按权重、Header 或 Cookie 进行分流让小部分流量先进入绿集群逐步放大比例出现异常时可一键切回完整的蓝集群。一、整体架构拓扑用户 → WAF安全防护透传请求头 → Nginx网关层实现 split_clients/header 路由灰度 ↙️ ↘️ upstream_blueV1 旧版本集群 upstream_greenV2 新版本集群WAF 配置关键点透传自定义 HeaderWAF 不能丢弃灰度标记头如X-Canary:1必须配置放行并透传给后端。职责分离WAF 只负责安全检测不要启用负载均衡和会话保持这些功能应由后端的 Nginx 处理。健康检查WAF 的后端应指向 Nginx 集群不要直接对接业务层的蓝绿机器。二、Nginx 配置完整示例2.1 upstream 定义两套业务集群# 蓝集群线上正在运行的旧版本 V1承接全部生产流量 upstream upstream_blue { server 10.0.1.11:8080; server 10.0.1.12:8080; server 10.0.1.13:8080; } 绿集群新版本 V2初始状态为 0 流量部署完成后进行预热和接口测试 upstream upstream_green { server 10.0.2.11:8080; server 10.0.2.12:8080; server 10.0.2.13:8080; }2.2 两种灰度策略生产环境常用二选一方案 A按比例权重灰度百分比放量最常用使用 Nginx 的split_clients模块基于客户端 IP 等变量进行哈希确保同一用户尽量路由到同一套环境保证会话一致性。http { # 灰度分流配置5% 的流量导向绿集群95% 的流量导向蓝集群 split_clients ${remote_addr}${time_iso8601} $backend_group { 5% upstream_green; * upstream_blue; } server { listen 80; location / { proxy_pass http://$backend_group; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }发布与回滚操作发布通过修改split_clients的百分比逐步放量例如 5% → 20% → 50% → 100%每次修改后执行nginx -s reload。回滚直接将配置改回100% upstream_blue然后nginx -s reload即可秒级切回整套旧集群。方案 B基于 Header/Cookie 的定向灰度指定用户或测试账号适用场景内部测试人员、特定用户群体先行验证不按全局百分比放量。前提WAF 必须配置放行X-Canary-Flag等自定义请求头。map $http_x_canary_flag $backend_group { default upstream_blue; 1 upstream_green; # 请求头携带 X-Canary-Flag:1 时流量导向绿集群 } server { listen 80; location / { proxy_pass http://$backend_group; proxy_set_header Host $host; } }测试命令示例curl -H X-Canary-Flag:1 http://your-domain.com组合策略生产环境中可以结合权重和 Header 两种方式实现更灵活的灰度控制。策略优先级优先判断 Header若未携带灰度头则 fallback 到按权重分流。2.3 组合模式Header 优先权重兜底# 1. 首先判断是否有灰度 Header map $http_x_canary_flag $pre_backend { 1 upstream_green; default ; } 2. 若无 Header则按权重分流例如 10% 灰度 split_clients ${remote_addr} $weight_backend { 10% upstream_green; * upstream_blue; } server { listen 80; location / { # 优先使用 Header 判断的结果 set $backend_group $pre_backend; # 如果 Header 未命中即 $backend_group 为空则使用权重分流结果 if ($backend_group ) { set $backend_group $weight_backend; } proxy_pass http://$backend_group; } }重要提示修改 Nginx 的split_clients或map配置后执行nginx -s reload即可生效无需重启 Nginx 服务不会中断现有连接。三、WAF 侧关键配置易踩坑点透传自定义灰度 Header确保 WAF 不会过滤或丢弃X-Canary-Flag等标记头否则 Nginx 无法根据 Header 进行路由。正确的上游指向WAF 的后端应配置为 Nginx 网关集群切勿直接指向业务层的蓝绿服务器。关闭 WAF 的负载均衡特性禁用 WAF 自身的会话保持、IP 哈希等负载均衡功能交由 Nginx 处理。日志记录配置 WAF 日志记录原始请求头便于后续排查哪些流量流向了绿集群。四、完整发布流程非容器环境初始状态蓝集群V1承载全部线上流量。绿集群部署新版本 V2此时流量为 0进行接口测试和应用预热。开始灰度调整 Nginx 的split_clients配置放出小比例流量如 5%至绿集群。双集群监控同时监控蓝、绿两套集群的 QPS、错误率、响应时间、GC 情况、线程栈、业务日志、慢 SQL 等核心指标。逐步放量确认无异常后逐步调大灰度比例5% → 20% → 50% → 80% → 100%。全量切换当 100% 流量都切至绿集群后蓝集群机器需保留不下线、不销毁作为回滚的兜底环境。循环发布稳定运行一段时间如半天或一天后下一轮发布时原蓝集群部署更新版本角色转换为新的“绿集群”如此循环。4.1 故障回滚流程在灰度过程的任何阶段若绿集群出现异常立即修改 Nginx 配置将split_clients的流量 100% 切回upstream_blue并执行nginx -s reload。优势整套旧的蓝集群环境完整可用无需重启业务程序或重新部署实现秒级回滚。回滚后可保留绿集群现场用于抓取 GC 日志、线程 Dumpjstack、堆快照heap dump进行问题排查。五、生产环境必须面对的约束虚拟机/物理机模式数据库向前兼容性蓝V1、绿V2集群会同时读写数据库。因此数据库表结构变更只能新增字段禁止执行删除字段DROP、修改字段类型等破坏性 DDL否则新旧版本共存时会报错。会话与缓存隔离若应用使用本地内存缓存两套集群的缓存是隔离的可能导致数据不一致。建议使用 Redis 等分布式缓存。用户 Session 不应存储在本地应统一存储至 Redis确保集群间共享。Nginx 配置变更规范修改配置前务必先执行语法检查nginx -t确认无误后再nginx -s reload。若有多台 Nginx 网关节点需确保所有节点的配置同步更新避免出现配置不一致。双集群监控灰度期间仍有流量在蓝集群因此必须同时监控蓝、绿两套集群的指标、日志和告警不可只关注新版本绿集群。资源成本需要维护两套完整的业务集群机器资源成本接近翻倍。六、与普通蓝绿发布一次性切换的区别普通蓝绿发布Nginx 配置直接全部切换至upstream_green。一旦切换所有用户立即访问新版本风险集中出现问题影响范围大。蓝绿 灰度发布通过 Nginx 的split_clients进行百分比灰度放量逐步将流量切至新版本。风险可控出现问题时可以快速切回完整的蓝集群影响范围小。七、常见坑点与避坑指南split_clients 哈希变量选择避免单独使用$remote_addr做哈希在多层代理场景下可能分布不均。建议拼接更多变量如${remote_addr}${request_uri}。WAF 过滤灰度 HeaderWAF 误将自定义灰度 Header 过滤导致基于 Header 的灰度策略完全失效。监控遗漏蓝集群灰度放量过程中只监控绿集群而忽略了蓝集群的指标无法全面掌握系统状态。数据库破坏性变更在灰度期间执行了不兼容的数据库 DDL如删除字段导致新旧版本应用同时运行时报错。过早销毁回滚环境在灰度未完全成功前提前下线或销毁了蓝集群机器失去了快速回滚的能力。八、面试关键点总结非容器环境下实现蓝绿灰度发布的核心要点架构层面维护蓝、绿两套完整业务集群WAF 负责安全与请求透传Nginx 作为网关实现流量分发与灰度逻辑。技术实现Nginx 利用split_clients实现百分比灰度或利用map实现基于 Header/Cookie 的定向灰度。发布流程采用小流量逐步放量的策略出现异常时通过nginx -s reload一键切回旧集群实现秒级回滚。环境约束数据库 schema 必须向前兼容蓝集群作为兜底环境在灰度成功前绝不能销毁。