兼容、迁移、灰度与退出条件
系统迁移需要在新旧版本并存时维持契约,用分批灰度控制风险,并以可验证的退出条件结束双轨运行。
1. 先列出所有兼容面
迁移影响的不只有 HTTP API。完整清单通常包括:
- 请求、响应、错误码和认证;
- 事件 schema、顺序和投递语义;
- 数据库 schema、数据格式和索引;
- 配置、开关和权限;
- SDK、批处理、报表和人工操作;
- 运行指标、告警和审计字段。
结构兼容也不等于行为兼容。接口仍返回相同字段,但金额舍入、默认排序或重试语义发生变化,调用方依然可能出错。
为每个兼容面登记所有者、消费者、版本和计划下线时间。无法列出消费者时,先增加访问日志或注册机制,再开始破坏性变更。
2. 使用扩展、迁移、收缩
数据库和接口变更可以分成三个阶段:
- 扩展:新版本增加字段或能力,同时兼容旧读写;
- 迁移:回填历史数据,逐批切换调用方和流量;
- 收缩:确认旧路径无使用后,删除旧字段和兼容逻辑。
例如重命名数据库列时,先新增新列并让应用兼容双读,确定唯一写入策略后回填,再切换所有读取方,最后删除旧列。直接 rename 会让滚动发布中的旧实例失效。
双写要定义部分失败和权威数据源。能通过数据库事务、outbox 或 CDC 完成的同步,不要依赖两次无保护的远程写入。
3. 迁移计划是一组状态
迁移对象可以是租户、数据分区、调用方或业务流程。为每一批记录状态:
待迁移 → 回填中 → 增量追平 → 影子验证 → 灰度 → 已切换 → 已关闭回退
状态转换要幂等,并保存开始时间、数据范围、校验结果和操作者。中断后可以从已确认位置继续,避免重新扫描全部数据。
批次大小由故障影响、处理时间和回退能力决定。先迁移内部或低风险对象,再覆盖高价值流量;每一批结束后留出观察窗口。
4. 灰度规则保持稳定可解释
灰度可以按租户、地域、账号哈希、客户端版本或业务类型分桶。一个对象在同一阶段应稳定命中相同版本,避免状态在新旧实现间来回跳转。
每个阶段预先定义:
- 流量比例和持续时间;
- 技术与业务指标;
- 最小样本量;
- 继续、暂停和回退阈值;
- 当班负责人和沟通渠道。
错误率、P99 和资源只是技术信号。订单成功、金额差异、人工工单和客户投诉等业务指标同样需要进入判断。
5. 影子和双读用于比较
无副作用查询可以使用影子流量或双读:主路径继续返回旧结果,新实现同步计算,系统比较结果和延迟。
比较器要忽略随机 ID、时间戳和无语义排序等可接受差异,并将真正差异按原因归类。差异率为零也不能证明写入安全;并发、事务和下游副作用仍要通过真实小流量验证。
影子请求要有独立标识,禁止触发通知、扣费或消息发布。它产生的负载也要计入容量,避免验证过程影响正式流量。
6. 回滚与向前修复分开设计
代码可以回滚,数据格式和外部事件未必可逆。迁移前需要分别回答:
- 路由如何切回;
- 新版本写入的数据旧版本能否读取;
- 已发送事件由谁继续处理;
- 正在进行的长流程如何归属;
- 回滚会不会重复业务副作用。
可逆变更准备自动回滚;数据库已经完成不可逆转换时,通常采用向前修复,并通过功能开关关闭风险路径。两类方案的权限、耗时和验证步骤都应演练。
回滚阈值要在上线前确定。故障发生后临时讨论“是否已经足够严重”,会浪费最关键的恢复时间。
7. 退出条件结束兼容期
迁移完成需要同时满足:
- 目标对象全部进入新路径;
- 技术和业务指标稳定达到目标;
- 数据回填完成,差异已清零或有批准解释;
- 没有旧接口、字段、事件或客户端流量;
- 运行责任、文档和告警已经转交;
- 旧资源、权限、同步任务和开关已删除;
- 回退窗口已按约定关闭。
每项条件都要有证据和负责人。“观察一段时间没问题”需要改成明确周期、指标和查询结果。
删除旧路径本身也走评审和灰度。先关入口并观察,再删除数据和基础设施,可以避免漏掉低频消费者。
8. 迁移完成后复盘收益
迁移结束后比较原有基线:发布速度、故障范围、延迟、成本和团队协作是否改善。目标未达到时,检查假设、边界和执行过程,决定继续优化、停止投入或恢复更简单的结构。
把兼容适配、临时同步和迁移开关留在代码里,会形成新的技术债。退出清单完成后再关闭项目,能够把人力从永久双轨维护中释放出来。
9. 面试题
9.1 一个核心接口怎样做到无停机迁移并保留回退能力
出现公司:阿里巴巴、字节跳动
考察重点
- API、事件、数据和行为兼容。
- 分批状态、影子验证和灰度阈值。
- 数据回退、向前修复与退出条件。
相关内容:第 1 节“先列出所有兼容面”至第 8 节“迁移完成后复盘收益”。
参考回答
我会先列出 API、事件、数据、配置和所有消费者,采用扩展、迁移、收缩:新旧版本先同时可用,完成数据回填和调用方切换,确认旧流量归零后再删除兼容。每个租户或分区有可恢复的迁移状态,先做影子比较,再按稳定分桶逐级灰度。
每一阶段预先定义错误率、尾延迟、业务结果、样本量和回退阈值。路由回退与数据恢复分开设计;不可逆数据变化准备向前修复。最终以全量切换、数据校验、稳定观察期、旧消费者归零、责任转交和旧资源删除作为退出条件,再比较迁移前后的业务和工程指标。