回答“大系统如何在不中断业务、不制造新债务的情况下,把旧链路迁到新能力上”
| 迁移场景 | 真正难点 | 判断重点 |
|---|---|---|
| 拆单体 / 拆服务 | 业务边界、事务边界和调用链一起变化 | 先收窄边界,再迁移流量,不要边拆边改语义 |
| 拆库 / 换存储 | 数据权威来源和一致性窗口变化 | 双写、校验、回放和旧数据冻结策略必须先设计 |
| 换基础设施 | 运行环境、容量、网络和观测语义变化 | 用影子流量和容量压测证明新底座能承接真实负载 |
| 替换核心链路 | 新旧链路同时影响订单、账户、库存或支付状态 | 必须定义不可回滚点、补偿策略和业务冻结窗口 |
| 阶段 | 目标 | 退出条件 |
|---|---|---|
| 0. 范围冻结 | 确认这次只迁承载方式,还是同时改变业务语义、数据模型和调用契约。 | 迁移对象、非目标、影响团队、权威数据源、不可碰边界全部写清。 |
| 1. 旁路建设 | 新链路先能接收真实输入,但不影响用户和外部副作用。 | 影子流量可跑,日志、指标、差异报告和容量基线可见。 |
| 2. 双写 / 双读验证 | 用可比较窗口证明新旧数据、状态和结果没有不可解释差异。 | 差异分类稳定,关键对象对账通过,异常样本有修复路径。 |
| 3. 小批量切流 | 按租户、地域、用户、业务线或比例逐步让新链路承接真实流量。 | 每批都有进入阈值、暂停阈值、回退动作和值守负责人。 |
| 4. 扩大与冻结旧写入 | 新链路成为主要承载,旧链路逐步只读、冻结或停止写入。 | 旧写入入口关闭,剩余消费者清单可追踪,回放窗口保留。 |
| 5. 退场与清债 | 删除旧接口、旧任务、旧表、旧报警、旧文档和临时兼容逻辑。 | 服务目录、运行手册、告警、权限和排障入口不再指向旧链路。 |
| 不可回滚点 | 为什么不能简单回退 | 替代策略 |
|---|---|---|
| 外部副作用已发生 | 支付、发货、短信、邮件、第三方调用无法假装没有发生。 | 提前设计冲正、补发、关闭、通知和人工接管,不把“回滚”写成空话。 |
| 数据结构已分叉 | 新旧表结构、字段语义或聚合口径变化后,旧系统可能读不懂新数据。 | 保留转换层、版本字段、回放脚本和差异对账,而不是临时手改。 |
| 客户端 / 消费者已升级 | 移动端、第三方或下游系统已依赖新契约,服务端回退会破坏兼容。 | 使用兼容窗口、双版本协议、消费者通知和废弃下线计划。 |
| 旧链路容量已释放 | 机器、队列、库表、人员值守和运行手册可能已经退掉。 | 在退场前定义保留期和应急恢复包,确认容量和权限还能临时接回。 |
| 误区 | 为什么危险 | 修正方式 |
|---|---|---|
| 把迁移当重构项目 | 只关注代码漂亮,忽略生产切换风险 | 迁移方案必须从流量、数据、回滚和运行窗口出发 |
| 先大爆炸上线,再补观测 | 上线当天才发现差异,已经没有可控退路 | 先建设差异观测、影子验证和小批量切流 |
| 长期保留新旧两套 | 迁移没有结束,系统复杂度反而翻倍 | 把旧入口、旧表、旧任务、旧报警的下线写成验收项 |
| 检查项 | 最低要求 |
|---|---|
| 范围冻结 | 本次迁移只改变承载方式,还是同时改变业务语义,必须写清 |
| 一致性验证 | 有差异口径、抽样策略、全量校验或关键对象校验 |
| 灰度计划 | 每批放量有指标阈值、暂停点、负责人和值守安排 |
| 回滚 / 补偿 | 明确可逆步骤、不可逆步骤、补偿脚本和审批人 |
| 退场验收 | 旧接口、旧任务、旧表、旧报警、旧文档都有关闭清单 |
| 登记字段 | 要写清楚什么 | 缺失后的后果 |
|---|---|---|
| 迁移范围 | 迁移对象、非目标、业务语义是否变化、影响团队、消费者和服务等级 | 迁移过程中顺手改语义,导致验证范围不断膨胀 |
| 权威与一致性 | 权威数据源、双写窗口、差异口径、一致性窗口、回放策略和异常样本处理 | 新旧差异出现时不知道是 bug、延迟、口径差异还是历史脏数据 |
| 切流计划 | 切流维度、批次、进入条件、暂停条件、回退条件、值守 owner 和业务告知 | 灰度只剩比例数字,没有明确谁决定继续、暂停或回退 |
| 不可逆边界 | 哪些步骤可回滚,哪些只能补偿;外部副作用、数据结构分叉和客户端升级如何处理 | 方案里写了回滚,真实失败时发现退不回去 |
| 退场清单 | 旧接口、旧任务、旧表、旧告警、旧权限、旧文档、旧 runbook 和剩余消费者 | 迁移上线后长期双轨,旧系统继续制造排障和认知成本 |
| 切换门禁 | 必须满足什么 | 失败时动作 |
|---|---|---|
| 差异门禁 | 关键对象对账通过,差异分类稳定,剩余差异有 owner 和处理路径 | 暂停放量,回到双写 / 影子验证,修复差异口径或数据问题 |
| 性能门禁 | 新链路延迟、错误率、容量水位和依赖瓶颈优于或不劣于旧链路 | 停止扩大流量,定位瓶颈,必要时回退到旧链路或限流 |
| 业务结果门禁 | 订单、支付、账户、库存、通知等业务结果与旧链路一致或差异可解释 | 冻结当前批次,拉业务 owner 参与裁决,不继续扩大影响面 |
| 操作门禁 | runbook、权限、回滚脚本、补偿脚本、告警、值守和沟通渠道已演练 | 不进入真实切流,只允许继续旁路验证或演练 |
| 退场门禁 | 旧链路调用归零或豁免明确,回溯窗口、监控下线和文档更新完成 | 不删除旧入口,继续追踪剩余消费者和例外期限 |
| 场景 | 最小落地包 | 验收信号 |
|---|---|---|
| 拆库迁移 | 先定义权威源、双写窗口、差异校验、读切换批次和不可回滚点;迁移期间禁止顺手改业务语义 | 新旧库关键对象差异可解释,读流量能分批切换并可暂停 |
| 核心链路替换 | 建立影子流量、结果比对、灰度闸门、回滚脚本和值守计划;每批切流有明确暂停阈值 | 每一批放量前后都有错误率、延迟、业务结果和差异报告 |
| 旧系统退场 | 列出旧接口、旧任务、旧表、旧告警、旧文档和剩余消费者;逐项关闭并保留回溯入口 | 旧链路不再承接生产流量,排障手册和目录不再指向旧入口 |
| 相关页 | 连接关系 |
|---|---|
| 架构偿债 | 迁移通常是偿债动作,但要避免把技术债转移到双轨复杂度里 |
| 数据库演进 | 拆库、换存储、字段迁移和历史数据处理都需要数据库演进纪律 |
| 数据契约 | 迁移期间最容易发生语义漂移,需要契约保证消费者不被静默破坏 |
| 发布工程 | 迁移的灰度、回滚和值守,本质上是更长周期的发布工程 |
| 可观测性 / SRE | 没有差异观测、错误率和延迟视图,迁移只能靠猜 |