#项目案例 #架构实战 #微服务 #演进

脱敏案例:老单体服务化的 9 个月——拆什么、不拆什么

一份脱敏的演进案例:一个跑了 6 年的老单体,怎么在业务不停的前提下拆成服务。重点是拆的次序与「先加边界后加网络」。

✍️ diunilaomei 📅 2026-08-08 📝 约 1041 字 ⏱️ 约 3 分钟
📑 章节目录
字号

案例说明:以下内容已脱敏,公司、业务量级与细节做了模糊化处理。写它的目的不是展示「拆成功了」,而是记录拆的次序和判断——多数服务化项目失败,不是拆得不对,是拆得太急。

背景:不是不能跑,是「改不动了」

一个跑了 6 年的单体应用,业务还在增长,但团队已经不敢动它:一次改需求要牵动十几个模块,上线窗口越来越长,一个模块的问题会把整站拖垮。团队最痛苦的不是性能,是变更的恐惧

这是一个典型的「改不动」问题。它和「性能扛不住」是两种病,药方完全不同——性能问题要拆热点,改不动的问题要先拆边界。

先做的一件事:模块化,而不是服务化

很多团队一上来就按「订单服务、用户服务」去拆,拆完发现服务之间到处互相调用,比单体还乱。

我们前三个月只做了一件事:在单体内部把边界画出来。按业务拆解的方法论把模块边界定清楚,接口在代码层面先隔离,数据访问也各走各的路(哪怕还是同一个库)。

判断标准很简单:模块 A 的代码里,不允许直接读模块 B 的表;要拿数据,走 B 暴露的方法。先在代码层把「不该有的耦合」消灭掉,网络层的事后头再说。

拆的次序:先拆「独立且低频」的,后拆「核心高频」的

我们的拆分顺序:

  1. 通知与消息模块:对外依赖多、核心链路不需要它同步参与,第一个拆出去,风险最小,还能顺便验证整套发布与监控流程。
  2. 数据分析与报表:读多写少、和交易链路只在写入点有接口,拆出去后可以独立扩缩容。
  3. 核心交易链路:最后才碰。等前两个拆完,团队已经把「发布、灰度、监控、回滚」这套动作练熟了,再拆最难的。

反向教训:把「用户服务」第一个拆是常见的冲动——因为它听着最独立。但实际上用户数据几乎被所有模块引用,拆它等于先啃最硬的骨头,大概率翻车。

过渡:双写与回滚,而不是「一次性迁移」

每个模块拆分都走同一套过渡流程:

  • 接口层先代理:单体先暴露 HTTP 接口,内部调用先切到接口,观察两周。
  • 数据双写 + 对账:需要迁库的模块,新旧双写,每天对账,差一条都不放行。
  • 保留回滚开关:切流量用开关控制,出问题 5 分钟内切回单体。服务化最怕「没有回头路」,开关就是回头路。

结果与代价(脱敏后)

  • 9 个月拆出 4 个服务,核心链路变更发布时间从「按天」降到「按小时」。
  • 代价也如实说:前三个月产出看起来「什么都没做」(其实在做边界),团队一度怀疑方向;双写对账的工程量和日常消耗比预期大 30%。

一句话总结

服务化的本质不是「把代码拆开」,是先把耦合拆开。耦合还在的时候上微服务,只是把同一个问题的答案,从「改不动」变成「查不动」。

方法论参考:业务架构拆解分布式系统设计:不要过度设计

相关阅读

栏目全部 →