为什么需要
再充分的测试,也无法完全模拟生产环境的真实流量。一个新版本上线,总有出问题的可能。
灰度发布(Canary Release / 金丝雀发布)的思路是:不一次性切全部流量,而是先让一小部分用户使用新版本,验证无误后再逐步扩大范围。
这个名字来源于煤矿中用金丝雀检测有毒气体——矿工先放一只金丝雀进去,如果鸟没事,人才进去。
常见灰度策略
一、按比例
最简单的做法:随机让 1%、5%、20%、50%、100% 的流量走新版本。
二、按用户特征
- 内部员工优先("吃自己的狗粮"):先让公司员工用;
- 按用户 ID 哈希:保证同一用户始终落在同一版本上(避免体验不一致);
- 按地域:先在一个小区域上线;
- 按会员等级/用户标签:先给愿意尝鲜的用户。
三、按流量特征
只让特定类型的请求(如只读请求、某个 API)走新版本。
技术实现
网关层分流
在 API 网关或负载均衡器上配置规则,把符合规则的流量路由到新版本的服务实例。
这对应用是透明的,实现简单。
服务网格
在微服务架构中,服务网格(如 Istio)可以在 Sidecar 代理层面做精细的流量切分,支持按权重、按 Header、按内容分流。
前端灰度
对于 Web 应用,可以通过 CDN 或前端配置,让部分用户加载新版本的静态资源。
特性开关(Feature Toggle)
更灵活的做法:代码里内置开关,通过配置中心动态控制某个功能是否对某类用户可见。
优势:功能上线与代码发布解耦。可以先发布代码(开关关闭),再在合适的时机打开开关;出问题立即关闭开关,无需回滚发布。
代价:代码里会积累判断分支,需要定期清理已经全量的开关,否则会成为技术债。
关键配套:监控与回滚
灰度发布不是"放出去就不管了",必须有:
一、实时监控指标
- 错误率、异常日志;
- 响应时间(P50/P95/P99);
- 业务指标(转化率、订单量等);
- 系统资源(CPU、内存、数据库连接)。
二、对比分析
灰度组和对照组(旧版本)的指标要对比着看,而不只是看绝对值——因为整体指标可能受其他因素(如流量波动)影响。
三、自动化止损
设定告警阈值,一旦灰度组的错误率显著高于对照组,自动 回滚或停止扩大灰度范围。
四、快速回滚能力
回滚必须足够快。如果回滚需要 30 分钟,那这 30 分钟内的影响可能已经很大。
数据库变更的特殊性
代码的灰度相对容易,但数据库 schema 变更要谨慎得多——因为数据库是所有版本共享的。
常见做法:扩张—迁移—收缩三步走:
- 扩张:先添加新字段/新表(旧版本忽略它),保证向后兼容;
- 迁移:新版本开始同时读写新旧字段,后台任务把历史数据迁移;
- 收缩:确认稳定后,删除旧字段。
这样可以在任意时刻回滚到旧版本而不会破坏数据。
一个原则
灰度的价值不在于"先给少量用户用",而在于给你一个在影响扩大之前发现问题并止损的机会。
所以,监控和回滚能力,比灰度策略本身更重要。
说明:本文为软件交付实践的公开知识整理。