本文目录
可渐进替换的关键,是每次只转移一个清楚的业务责任
绞杀者模式通过入口或应用边界把一部分请求交给新实现,其余仍由旧系统处理。适合旧系统能够持续运行、模块能被隔离并且入口可控制的场景。实施时先选有明确价值与依赖边界的模块,定义新旧调用和写入主责,验证后逐步转移;临时适配层、双系统运维和旧功能退出都属于工程范围。
动手前确认四个条件
| 条件 | 可行信号 | 不成立的后果 |
|---|---|---|
| 请求入口 | 网关、路由或应用内调用点可以稳定分流 | 绕过新入口的调用仍进入旧逻辑,结果无法统一 |
| 功能边界 | 模块输入输出、状态变化与依赖已可描述 | 一次替换牵动整个系统,失去渐进价值 |
| 过渡能力 | 旧系统可以继续运行,并有人员维护新旧两侧 | 共存成本没有预算,适配层长期无人负责 |
| 退出路径 | 旧入口、任务与调用方有停用标准和责任人 | 新模块上线了,旧模块仍长期产生写入与维护费用 |
第一块模块应能交付价值,也能独立验证
不要只选代码最短的模块。更合适的起点是业务负责人明确、输入输出稳定、关联流程可盘点,而且替换之后能解决真实问题的能力。
例如只读查询、边缘工作台或规则相对独立的流程可以列为候选,但是否适合仍取决于实际依赖。把模块的同步接口、后台任务、报表和人工操作一起画出。如果每个操作都直接访问其他模块的内部状态,应先建立受控边界,而不是新建一个服务就称为完成拆分。
- 比较业务价值、规则清晰度、调用关系与退出难度。
- 明确模块负责人和它对外承诺的行为。
- 用一个完整用户任务定义首个替换成果。
路由规则围绕业务主键,避免一次流程进入两套实现
按路径分流、按租户分流和按业务主键分流各有适用条件。选法要保持一笔业务在完整生命周期中的处理归属,不能只按单次请求随机切换。
列出浏览器、移动端、内部接口和批处理是否经过同一入口。订单创建走新模块、修改却走旧模块,可能造成语义冲突。入口需要记录路由依据、版本和请求标识,便于追查。网关新增跳转还会带来延迟和可用性约束,必须验证容量与故障处理,不把它当成无成本透明层。
对于生命周期较长的业务,归属信息应持久保存或能够稳定推导,不能因配置更新而随意变换处理者。需要变更归属时,先说明现有状态由哪一侧接续处理,并测试已创建对象、未完成审批和历史查询。
- 按业务对象定义稳定路由规则与覆盖范围。
- 核对内部调用、回调和任务是否绕过入口。
- 为无法识别归属的请求设置可审计的处理策略。
适配层翻译旧语义,控制过渡代码的生长
旧字段命名、状态值和错误码可以在边界处转换,让新模块保留自己的模型。适配层不宜同时承担大量新业务,否则会变成另一个难以替换的系统。
把翻译规则列成映射清单,例如旧状态哪些能转换、哪些必须人工处理。转换失败应保留可定位的原因,不能静默填默认值。每个临时接口登记调用方与预期退出条件;新业务功能尽量由新模块负责。保持适配层薄而可测试,有助于后续判断哪些代码可以删除。
适配层对超时、不可识别状态和字段缺失的处理也属于契约。先用固定样例验证,再通过联调核对真实旧接口行为。错误不能被统一吞掉后返回空结果,否则业务人员无法分辨暂无数据与调用失败。
- 对字段、状态、错误和时间口径形成显式映射。
- 将兼容转换与新增业务计算分开实现和验收。
- 为临时接口标明主责、观察方式及清理条件。
同一业务对象的写入主责必须明确
新旧系统都能读某类数据,不意味着都应自由修改它。先定义谁处理命令、谁保存最终状态,再设计其他一侧如何取得结果。
单一写入责任可以减少新旧规则互相覆盖。若过渡期确需两侧写入,必须有明确的一致性方案、差异检测与失败补偿,不能以“都写一次”代替设计。本文聚焦模块责任转移;具体表结构修改和历史数据回填应由单独的数据变更方案处理,避免把两类风险揉在一次验收里。
- 逐项列出命令、状态拥有者和读取方式。
- 验证新旧模块对同一对象不会竞争处理。
- 标记数据一致性限制及需要人工处理的异常。
实施依次完成边界、验证、转移和退出
先跑通新模块的独立业务样例,再验证与未替换模块的交互,最后转移真实请求。每一步都要能解释系统现在由谁负责哪个动作。
第一步建立入口和兼容映射;第二步在隔离环境运行正常、异常及重复请求样例;第三步选定业务群体开始转移并观察业务结果。对写操作做影子比较时不能让影子路径再次产生支付、通知或库存变更。转移稳定后再删除旧模块的执行入口与后台任务,保留必要历史查阅能力。
- 为首个模块完成关系图、映射表与可执行样例。
- 转移前确认副作用只在被指定的一侧发生。
- 退出时搜索旧入口引用,核对任务、报表和合作方。
共存窗口不足或入口不可控时,需要改选路线
小型系统一次替换成本低,或旧环境必须很快关闭时,绞杀者模式可能不划算。没有办法控制请求和内部调用,也很难形成可靠的渐进替换。
无源码系统不必一律放弃改造,但可做的事情取决于外部接口与入口控制能力;无法停用内部逻辑时,功能归属尤其需要验证。长期保留适配层也可以是合理选择,例如服务仍在使用旧客户端,但应把它作为长期产品维护,而不是永远没有负责人、没有测试的临时代码。
- 先评估维护双系统是否超过业务可以承担的投入。
- 明确必须快速退役的时间约束与未替换范围。
- 对保留适配层给出长期责任、测试和版本策略。
需求讨论中的问题
绞杀者模式是不是必须改成微服务?
不是。新实现可以是模块化单体、独立服务或其他合适的部署形态。核心是逐步转移业务责任,并使未替换部分继续工作。
可不可以让新旧系统同时写数据?
要有明确的主责、一致性机制和异常处理。缺少这些设计时,容易互相覆盖或重复执行。优先评估由一侧接收业务命令,另一侧通过受控方式获取结果。
旧系统没源码还能这样做吗?
若能够控制外部入口并有稳定接口,仍可评估部分外部替换;但无法关闭内部旧逻辑和改变内部调用会限制迁移范围,需要验证后再承诺。
首个模块替换的验收清单
可逐项勾选,辅助本次阅读;刷新页面后不保留。
参考资料
技术概念可进一步阅读以下资料;文中的业务场景与实施清单用于方案讨论。
- Microsoft Azure Architecture Center · Strangler Fig pattern
核对入口分流、旧系统共存、过渡成本、网关瓶颈与适用限制。
- Microsoft Azure Architecture Center · Anti-corruption layer pattern
核对边界适配翻译新旧语义并保护新领域模型的职责。
需要一边维持业务,一边替换旧模块?
提供系统入口、拟替换模块、关键依赖和共存期限,月弦科技可以帮助评估边界与首个模块的验证方案。