摘要:从不拆到拆,业界其实趟过好几代"手术方式":大爆炸重写、分行移植、垂直切分,最终沉淀出今天用得最多的"绞杀者模式"。本文用一台单体电脑商城做时间轴回放,讲透每种术式为什么敢于开始、为什么又栽了,并给出选术式的三条经验法则。
决定要拆之后,第二个问题冒出来:怎么拆才算安全? 这是外行最容易踩的雷。很多人以为微服务迁移就是"重写一版新的,然后一把切到新系统"。这条号称最快实则最险的路,我们叫它大爆炸。下面我们把这台电脑商城当试验田,回放三代拆法。
大爆炸的意思很简单:别再修这坨老代码,用新架构从零写一套,写好了整个替换。
想法不坏,坏在它违背了三条常理。第一,重写往往低估工作量:老系统里积累了五年才长出来的业务规则,除非有足够的测试兜底和文档,否则"重写"基本等于"重猜"。第二,替换是二元的:要么新系统全好,要么全不能用,中间没有灰度安全网,基本运营叫停你就得手撕回去。第三,你失去了对照改进的机会:老系统是唯一的"真相",而你在黑盒里重造它。
上世纪九十年代末到本世纪初的技术团队,很多就是栽在这一刀上——重写的时间成本让业务方失去耐心,切换当天故障让口碑一夜崩塌。今天几乎没人建议大爆炸,除非老系统小到可以几天重写且业务完全可逆。
吸取大爆炸的教训,大家想:既然整锅端太险,那就"一行一行建地基,一块一块搬进新楼"。于是出现两种拆法。
分行移植:新老系统并行,按数据/功能的粒度分批搬。比如先把"商品列表"这个只读模块迁到新服务,量小、风险低。
垂直切分:按业务线切开系统,比如把"商城"切成"买家端/卖家端/支付线"三条垂直可用单元,每条内部是完整闭环。垂直切分比分层切分更符合高内聚原则,因为它是按"业务能力"而不是"技术层次"切。
这两种比大爆炸稳,但都有共通的麻烦:迁移期间两套系统要长期并行、数据要双向同步,投入的人力常比想象中多,而且容易演成"永远在迁移中"。
今天用得最多、也最稳妥的是绞杀者模式(Strangler Fig,得名于榕树缠绕宿主树慢慢把它绞掉的生长方式)。它不再"把老系统搬走",而是在老系统外围长一圈新服务,逐个能力迁移并接管入口:

绞杀者模式最大的优点,也是它唯一的副作用:它不重写,所以老代码里的坏味道会原样搬进新服务。也就是说,绞杀者是"搬迁"而非"清洗"。如果你希望顺带消灭技术债,那每一块被迁移的能力都应该加一轮重构预算,否则你只是把"一坨大泥球"切成"很多坨小泥球"。这个分寸,我们到第 8 章的架构演进里还会再谈。
不管选哪种渐进术式,你几乎总会在一段时间里处在"老单体 + 一堆新服务"同时存在的混合态。很多团队一到这个阶段就慌,觉得"乱、丑、又贵",甚至想干脆重来一次大爆炸。这个念头最要不得。
要理解混合态其实就是微服务迁移的正常长相:老单体里的某个能力被"绞杀者"接手后就不再更新,但它们共享同一份数据与同一批用户的入口。真正要盯的不是"看着整不整洁",而是三件事——这群在新老系统间流通的请求有没有稳定接入点(网关)、同一份业务数据在新老两端是否只由一方负责写、每一次接管是否都能独立回退。只要这三条成立,混合态再久都是安全的;反之,哪怕你一天切完,也是危险的。
所以判断一台迁移手术健不健康,请把它想象成"一场持续好几个季度的手术",而不是"一个周末的工单"。在真的把最后一个能力搬完之前,不要急着宣布"我们已经是微服务了"——也请别人问"你们到底算单体还是微服务"时,坦率回答:我们正在拆,而且很安全。
选术式容易陷入"大爆炸 All in vs 绞杀者稳字当头"的两难,其实还有一个更伤脑筋的现实问题常被绕过:拆的时候,旧的、已经被新能力接管的代码,到底什么时候能删? 大爆炸是一刀清,绞杀者是慢慢留。但很多团队选了温和的渐进路线后,却把"老代码还在那"当成心理安慰,长期不去清理,结果老和新并行维护两套真相,比谁单独都累。
务实的手法是给每块迁移的能力设一个"清理承诺":当某个老能力已被新服务全量接管、且线上观察一段(比如两周)没有回退请求后,就把对应的老代码和旧数据访问收掉,而不是无限期留在那里。这样你既拿到了渐进式拆分的低风险,又不会让它悄悄滑成"搬到一半就停下"的僵尸迁移。真正的绞杀者是"接一块、清一块",而不是"接了一堆、什么都不敢删"。
把三种术式摆开,容易让人觉得"得挑一个",实际上成熟团队几乎都不是纯用某一种。大爆炸基本不用(除非系统小到可以几天重写且业务完全可逆),但分行移植和绞杀者经常在同一台系统上一起出现:某个低频模块用分行移植先搬走,核心的交易链路用绞杀者慢慢接管;甚至同一个能力,前期用垂直切分验证边界,稳定后再用更细的粒度继续优化。判断标准不是"哪种术式更酷",而是"这台系统的数据能不能双向同步、回退窗口有多大、迁移期间的运维能力跟不跟得上"。别把术式当成信仰之争,它只是你手里可以按需拼接的工具箱。