4. 迁移方案设计:迁移策略与回滚预案
方案设计这一步,说白了就是回答三个问题:怎么切?怎么验证?怎么回来?
我见过太多团队,花了两周搭流水线,结果上线时一拍脑袋选了个策略,出问题后又没有回滚手段,最后全员通宵回退代码。嗯,这种经历一次就够了。
这一章,我把三种主流迁移策略掰开揉碎讲清楚,再附上我自己的回滚预案模板。你照着搭,至少能保证:出事了,你能在 10 分钟内把用户拉回安全区。
4.1 三种迁移策略的核心逻辑
先看一张总览图,把三种策略的流量切换方式、风险等级和适用场景串起来。
4.2 蓝绿部署:最暴力也最可靠
蓝绿部署的思路很简单:同时维护两套完整环境。蓝环境跑当前生产版本,绿环境部署新版本。验证通过后,负载均衡器一键切换流量。
我在项目中遇到过最经典的场景:某金融核心系统迁移。业务要求停机时间不超过 30 秒,但数据库 schema 变更需要跑 20 分钟。怎么办?
我们用蓝绿部署 + 数据库双写解决了。提前在绿环境跑完 migration,数据同步追上后,直接切 DNS。整个过程用户无感知。
蓝绿部署的 Pipeline 示例
# 伪代码:蓝绿部署流水线核心步骤
stages:
- deploy-green
- smoke-test
- switch-traffic
- health-check
- cleanup-blue
deploy-green:
script:
- kubectl apply -f k8s/green-deployment.yaml
- kubectl rollout status deployment/green-app -n production
smoke-test:
script:
- curl -f https://green.internal.example.com/health
- ./run-smoke-tests.sh --target green
switch-traffic:
script:
- kubectl patch service myapp -n production \
--patch '{"spec":{"selector":{"version":"green"}}}'
health-check:
script:
- curl -f https://api.example.com/health
- ./verify-business-logic.sh
cleanup-blue:
script:
- kubectl delete deployment blue-app -n production
- kubectl delete configmap blue-config -n production
when: always
4.3 滚动升级:温水煮青蛙,但安全
滚动升级适合微服务架构。它不会一次性替换所有实例,而是逐个或逐批替换。Kubernetes 的 Deployment 默认就是滚动更新策略。
我个人习惯把滚动升级的批次大小控制在 20% - 30%。太小了耗时太长,太大了风险集中。举个例子:10 个 Pod 的服务,我分 3 批,每批 3-3-4 个。
滚动升级的关键参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
| maxSurge | 25% | 升级期间允许超出期望副本数的比例 |
| maxUnavailable | 25% | 升级期间允许不可用副本的最大比例 |
| minReadySeconds | 30 | 新 Pod 就绪后等待多久才继续下一批 |
| progressDeadlineSeconds | 600 | 升级超时时间,超时自动回滚 |
4.4 金丝雀发布:用真实流量做验证
金丝雀发布的核心是:让一小部分真实用户先尝鲜。流量比例通常从 1% 或 5% 开始,观察一段时间后逐步放大。
你想想看,为什么叫金丝雀?以前矿工带金丝雀下井,鸟对毒气敏感,鸟死了人就撤。金丝雀发布也是这个道理 —— 让新版本先暴露在低风险流量下,出问题也只影响少数用户。
金丝雀发布的流量路由策略
# Istio VirtualService 示例:5% 流量到金丝雀版本
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-canary
spec:
hosts:
- myapp.example.com
http:
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: myapp
subset: canary
weight: 100
- route:
- destination:
host: myapp
subset: stable
weight: 95
- destination:
host: myapp
subset: canary
weight: 5
金丝雀发布的典型节奏:
- 1% 流量 → 运行 10 分钟,检查错误率和延迟
- 5% 流量 → 运行 30 分钟,检查业务指标
- 20% 流量 → 运行 1 小时,观察是否有异常
- 50% 流量 → 运行 2 小时,确认稳定
- 100% 流量 → 全量发布,清理金丝雀环境
每个阶段如果指标异常,立即切回 0%。
4.5 回滚预案设计:别等出事了再想
回滚预案不是写在文档里吃灰的。它应该是可执行的、自动化的、经过演练的。
我曾经吃过一次大亏:某次数据库迁移,回滚脚本写好了但没测试。结果真出问题时,回滚脚本跑了一半报错,数据处于中间状态。最后 DBA 手动修了 6 个小时。
从那以后,我的回滚预案必须满足三个条件:
- 可自动化:回滚操作必须能一键触发,不需要人工 SSH 上去敲命令
- 可验证:回滚完成后有自动化校验,确认数据一致性和服务健康
- 有时限:明确回滚的 RTO(恢复时间目标),超过时限自动升级
回滚预案模板
| 阶段 | 操作 | 负责人 | 预期耗时 |
|---|---|---|---|
| 检测异常 | 监控告警触发(错误率 > 1% 或 P99 延迟 > 500ms) | 值班 SRE | 1 分钟 |
| 确认回滚 | 在 CI/CD 平台点击「回滚」按钮 | 值班 SRE | 30 秒 |
| 执行回滚 | Pipeline 自动执行:切流量 / 恢复数据库 / 回退版本 | 自动化 | 2-5 分钟 |
| 健康检查 | 自动运行 smoke test 和业务校验 | 自动化 | 1 分钟 |
| 通知通报 | 发送回滚完成通知到企业 / Slack | 自动化 | 10 秒 |
4.6 策略选择矩阵
最后,给你一个我实际项目中用的决策矩阵。遇到迁移场景时,对着这个表选策略就行。
| 场景 | 推荐策略 | 理由 |
|---|---|---|
| 核心交易系统 | 蓝绿部署 | 需要秒级回滚,资源消耗可接受 |
| 无状态 API 服务 | 滚动升级 | 资源利用率高,分批验证风险可控 |
| 新功能灰度上线 | 金丝雀发布 | 用真实流量验证,影响面最小 |
| 数据库迁移 | 蓝绿 + 双写 | 数据一致性要求高,需要完整环境验证 |
| 配置变更 | 金丝雀 + 滚动 | 先小范围验证配置正确性,再全量推送 |
说白了,没有银弹。每种策略都有它的适用边界。我的习惯是:在 Pipeline 里同时保留三种策略的模板,上线前根据变更类型和风险等级,选一个或组合使用。