灰度发布
# 灰度发布:新版本别一次性全量推
前公司有次发版,直接全量替换,结果新版本有个空指针,上线十分钟,一半用户报错。从那以后我们改成了灰度:先放一小部分流量,看清楚了再逐步放开。这篇说说灰度怎么做,不只是工具层面,还有几个容易忽略的点。
## 灰度的核心是什么
不是「新版本先上线」,而是「让少量真实流量先走新版本,验证没问题再扩大」。
核心是三件事:
1. 能把流量按规则分到新旧版本;
2. 能观测新版本的真实表现;
3. 出问题能快速回退。
缺了任何一个,灰度都是假的。
## 几种分流方式
**按比例**:10% 流量走新版本。最简单,但用户可能一会儿新一会儿旧,体验不一致。
**按用户**:同一用户始终走同一版本(比如按 uid 哈希)。体验一致,适合功能类改动。
**按机器/节点**:新版本只部署在部分节点,流量按节点分。实现简单,但粒度粗。
**按地域/租户**:指定区域或租户先升级。适合 B 端产品,能协调。
选哪种,看你的业务和你想验证什么。
## 实现方式
**Nginx 权重**:
```nginx
upstream backend {
server 10.0.0.1:8080 weight=9; # 旧版本
server 10.0.0.2:8080 weight=1; # 新版本
}
```
简单直接,适合按比例。
**K8s 多版本 Deployment + Service**:两套 Deployment 打不同标签,Service 按比例转发,或者用 Ingress 按 header 路由。
**特性开关(Feature Flag)**:代码里加开关,新旧逻辑都在,按用户或白名单开关。发布和上线解耦,回滚就是关开关。这个最灵活,但要处理好开关的生命周期,别留一堆僵尸开关。
## 观测是关键
灰度没有观测,就是盲人摸象。要重点看:
- 新版本的错误率(和旧版本对比)
- 响应时间 P99
- 关键业务指标(下单成功率、支付成功率)
- 日志里的异常
建议按版本维度打标签,监控能分开看。不然流量混在一起,看不出新版本的问题。
## 回滚要快
灰度的价值在于「出问题影响小」。所以回滚必须快:
- 流量切回旧版本(改权重、改路由)
- 或者关掉特性开关
- 数据库变更要能兼容(见下)
如果回滚要半小时,灰度就失去意义了。
## 数据库变更最容易翻车
应用可以灰度,数据库不行。新旧版本同时跑,都要能读同一份数据。
原则:**先加后删,向前兼容**。
- 加字段:先加可空字段,新旧版本都能跑
- 改字段:新增字段、双写、迁移、再删旧字段,分多次发布
- 删字段:确认没代码用了再删
千万别在一次发布里既改代码又改表结构,一旦回滚,数据库改不回去。
## 一个实操清单
发布前:
- 新版本部署到少量节点
- 数据变更保证兼容
- 监控按版本区分
- 准备好回滚方案
灰度中:
- 先 1%~5% 流量,观察 30 分钟
- 看错误率、延迟、核心指标
- 没问题逐步放大到 25%、50%、100%
出问题:
- 立即切回旧版本
- 保留现场日志
- 复盘
## 几个坑
**只灰度不观测**:放了流量不看指标,等于没灰度。
**灰度时间太短**:刚放五分钟就全量,问题还没暴露。
**新旧版本数据不一致**:缓存 key 变了、字段含义变了,用户看到混乱数据。
**开关没清理**:功能稳定了开关还留着,代码越来越乱。
## 小结
灰度不是工具问题,是流程问题。分流、观测、回滚三件事缺一不可,数据库兼容是最容易被忽略的雷区。
新版本上线,慢一点没关系,稳一点更重要。一次全量推出去,出了问题就是全体用户一起承担。
- 点赞
- 收藏
- 关注作者
评论(0)