灰度发布系统让新旧版本同时在线,先把一小部分生产流量导到新版本,观测无误再逐级放量到全量。核心由”流量路由 + 放量阶梯 + 指标监控 + 异常回滚”四块组成。控制切流靠权重或内容规则,默认阶梯 5%→20%→50%→100%。下文给出设计与可直接用的配置。
一、灰度发布解决什么风险
一次性全量替换,新版本的隐藏缺陷会瞬间冲击所有用户。灰度发布把风险关在极小范围内:先放 5% 流量验证,出问题只影响少数用户,并能在分钟级切回旧版本,把爆炸半径压到最小。
二、三种渐进式发布怎么选
| 策略 | 资源占用 | 切换方式 | 适用场景 |
|---|---|---|---|
| 蓝绿部署 | 双倍实例 | 整体切流 | 无状态、可停机切换 |
| 金丝雀/灰度 | 少量额外实例 | 权重逐步放量 | 无状态微服务主流 |
| 全链路灰度 | 多服务协同 | 按标签贯穿 | 多服务联动变更 |
金丝雀是无状态微服务最常用方案:新旧集群共存,网关或服务网格按权重把小比例流量导入新版本,逐级放量直至替换旧版。
三、控制流量的两条路径
3.1 按流量比例
按预设百分比随机分发,适合通用性能与高可用验证,配置最简单。两种方式也能叠加:先按内容路由放内部员工,再按权重逐步放量给普通用户。Nginx 用 split_clients 就能切:
split_clients "${remote_addr}" $variant {
10% canary;
* stable;
}
upstream stable { server 10.0.0.1:8080; }
upstream canary { server 10.0.0.2:8080; }
server {
location / {
proxy_pass http://$variant;
}
}
3.2 按内容路由
按请求特征(Header、用户 ID、地域、设备)把匹配流量导到新版本,适合 A/B 测试或内部员工先行。Istio 用 VirtualService 配置权重与规则,对业务代码零侵入,还能结合 Prometheus 看灰度指标:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: orders-route
spec:
hosts: ["orders"]
http:
- match:
- headers:
x-canary:
exact: "true"
route:
- destination: { host: orders, subset: v2 }
- route:
- destination: { host: orders, subset: v1 }
weight: 90
- destination: { host: orders, subset: v2 }
weight: 10
四、标准放量流程
- 部署新版本实例(v2),与 v1 同时在线,初始仅 5%~10% 或单实例;
- 配置路由规则,导入首批小流量,其余走 v1;
- 观察窗口内监控错误率、响应延迟、业务指标;
- 指标正常则放量到 20%,重复观察;
- 继续 50% → 100%,每级都先校验再放量,禁止跳阶;样本不足就全量等于主动放大未知风险;
- 任意一级异常,立即把流量全切回 v1,排查后再来。
观察窗口按流量特征动态适配:万级 QPS 核心服务 5~10 分钟即可积累样本,中低流量服务需 30 分钟到 2 小时。错误预算紧张时自动拉长窗口、缩小步长。
五、两个落地要点
监控必须到位,错误率、RT、转化率要实时可视,否则放量等于盲飞。回滚要一键可达,灰度系统的价值一半在”放量快”、一半在”回退快”。GitLab 的 Canary Ingress 就通过流量权重接口在稳定版与金丝雀间调节,异常即降权重到 0。
六、蓝绿部署:另一种思路
蓝绿部署同时跑两套完整环境,流量从绿切到蓝是一次性整体切换,回滚也只要切回。它资源占用翻倍,但切换干净、无中间态,适合允许短暂停机、强调”要么全旧要么全新”的场景。它和灰度的本质区别是切换粒度:蓝绿是环境级,灰度是流量级,后者更省资源也更能观察渐进过程。
七、全链路灰度的难点
单服务灰度容易,多服务联动变更才棘手。一个请求穿过网关、订单、库存多个服务,要让同一批用户始终命中各服务的 v2,就得用染色标签(如 userId 取模或请求头)贯穿整条调用链,靠网关与服务网格协同路由。染色通常在网关入口打标,下游各服务按标路由,整条链路保持一致。否则用户会在新旧版本间反复横跳,状态错乱。
八、监控指标要细化
放量的判据不能只看”没报错”。核心服务盯错误率、P99 延迟、饱和度;业务侧盯下单成功率、转化率、客单价。给每级放量设明确的通过阈值,指标越线立即暂停甚至回退,把决策从”感觉稳了”变成”数据达标了”。
九、会话一致性不能忘
按用户切流时,同一用户在一次会话里不应在 v1/v2 间乱跳,否则购物车、登录态会错乱。Kubernetes 可开 sessionAffinity: ClientIP;灰度路由按 userId 取模比随机比例更稳,保证同一用户始终命中同一版本。
常见问题(FAQ)
Q1:初始灰度放多少流量?
按最小有效原则,取集群 5%~10% 或单实例,兼顾影响面与样本量。
Q2:按比例是按内容路由怎么选?
通用验证用比例;A/B 测试或指定人群用内容路由。
Q3:放量中发现异常怎么办?
立即把流量全切回旧版本,定位修复后再重新灰度。