从单体到微服务,再到模块化单体
2026.09.11
架构演进不是一条只能向前的直线,而是一次次根据团队规模、业务节奏和运维能力做出的重新权衡。
过去十年,微服务几乎是「现代架构」的同义词;几乎所有技术分享的终点都是「我们把它拆成了服务」;但最近几年,一个反向的趋势开始出现在一线团队的实践里——把过度拆分的服务重新收敛为模块化单体。这不是技术上的倒退,而是对一次集体误判的纠正:很多团队当初拆分时,解决的是组织问题,却在过程中引入了自己无力承担的分布式复杂度。

一、当年为什么要拆
先说清楚拆分的合理性,否则容易被误读成对微服务的否定。
微服务解决的是一类真实而具体的问题:当团队规模超过某个临界点,一个代码库上的协作成本会急剧上升——改一行代码要跑全量回归、发一次版要等所有人、一个技术债拖住所有业务线;这时按业务边界拆分服务,让每个团队拥有独立的代码库、独立的发布节奏、独立的技术选型,协作成本确实会下降。
第二个理由是弹性与隔离:把高负载模块独立出来,可以单独扩容,避免为一个小流量模块的峰值成本买单;把非核心模块独立出来,可以让它的故障不拖垮核心交易链路。
第三个理由是技术异构:老系统用 Java、新推荐算法用 Python,与其强行统一,不如用服务边界把它们隔开。
这些理由都成立;问题出在,很多团队在不具备相应条件的时候也照着做了。
二、拆开之后的账:分布式单体
微服务的代价往往在拆分一年之后才浮现。
分布式事务是最先撞上的墙:原本一个数据库事务能保证的一致性,现在要跨越网络边界,于是引入 Saga、TCC、本地消息表,每一种方案都有自己的复杂度与失败模式;调试难度急剧上升:一次用户请求经过六个服务,日志分散在六个系统里,排查一个偶发问题需要拼凑完整链路;测试成本成倍增长:本地跑不起来,必须依赖一整套联调环境,端到端测试变得脆弱且缓慢;运维负担从「部署一个应用」变成「维护一套编排平台、一套服务网格、一套链路追踪」。
最坏的结果是所有代价都付了,收益却没有拿到——服务边界划得不对,模块之间仍然互相依赖,改一个功能还是要同时发布五个服务;这就是所谓的分布式单体:它同时继承了大系统的复杂度和单体系统的耦合。
定义一个实用的判断标准:如果你拆出来的服务无法独立部署、无法独立演进、也无法由单个小团队完整负责,那么这次拆分只增加了成本,没有带来收益。

三、模块化单体的回归
模块化单体的主张很朴素:在进程内保留模块化的边界,但不引入网络边界。
具体做法是:一个代码库、一个部署单元、一个数据库(或至少一个数据库实例,按 schema 划分所有权);但在代码层面强制划分模块,模块之间只能通过明确的公开接口通信,禁止跨模块直接访问对方的内部实现与数据表;模块的所有权、依赖方向、可见范围都有明确的规则,并且用自动化检查来保证这些规则不被破坏。
它保留了单体的三个关键优势:本地开发与调试简单、事务边界完整、部署与运维成本低;同时通过模块边界与架构检查,拿回了微服务最想要的那部分纪律——清晰的边界、明确的所有权、可控的依赖方向。
它的代价也很清楚:模块之间无法独立部署,无法独立扩缩容,无法使用不同的技术栈;因此它适合的是团队规模适中、业务复杂度可控、对独立发布节奏需求不强的场景。
四、如何判断该不该拆
与其争论微服务和单体哪个更好,不如用四个问题来定位自己。
团队规模:一个模块能否由 8 人以内的团队完整拥有?超过之后协作成本才开始具备拆分的正当性;团队只有十几个人却拆出二十个服务,是典型的错配。
发布独立性:是否存在「A 团队的发版正在被 B 团队的进度阻塞」这类具体痛点?如果发布节奏冲突并不频繁,独立部署的收益就不足以覆盖分布式成本。
运维能力:是否具备(或愿意投入)可观测性体系、分布式追踪、自动化部署、故障演练这些基础设施?缺少这些能力的微服务,就是一套难以定位故障的黑盒。
数据一致性要求:核心业务是否强依赖跨模块的强一致性事务?如果是,拆分带来的分布式事务复杂度会直接压在业务正确性上,代价极高。
四个问题的答案如果都指向「不需要拆」,那模块化单体就是更理性的选择;如果部分指向「必须拆」,那么正确的做法也不是一次全拆,而是沿着真实的痛点逐步演进。

五、演进式拆分的路径
如果确实需要拆,推荐的做法是把大规模重构拆成三个可回退的阶段。
第一阶段:整理边界。先在单体内把模块边界划分清楚,让依赖方向单向流动,把跨模块的直接调用改为接口调用;这一步不改变部署形态,风险最低,但收益最大——它让后续的拆分成为「搬家」而不是「考古」。
第二阶段:按痛点抽取。只抽取那些有明确独立诉求的模块:需要独立扩缩容的、需要独立技术栈的、有严格安全隔离要求的;每抽一个服务,都要补齐它的监控、日志、告警与回滚方案;不要为了「架构统一」而拆。
第三阶段:建立治理。当服务数量超过个位数,服务目录、接口契约管理、版本兼容策略、链路追踪、容量规划就需要形成制度;这一步如果缺失,服务会退化成新的分布式泥球。
反过来,如果已经拆得过细,合并同样是一条正当路径:把那些始终一起发布、共享同一份数据、由同一个团队维护的服务合回一个进程,往往能立刻换来显著的效率提升和更低的事故率;承认并纠正一次过度设计,比坚持一个不再成立的架构假设要专业得多。
六、总结
架构没有正确答案,只有与当下约束相匹配的答案;微服务和单体不是先进与落后的关系,而是两种不同权衡方式的取舍:前者用分布式复杂度换取独立性与弹性,后者用集中式复杂度换取简单性与一致性。
选择时真正需要问的不是「哪种架构更先进」,而是「我们团队的规模、业务节奏和运维能力,能承担哪一种复杂度」;把这个问题的答案写下来,你得到的就不只是一次技术选型,而是一条能被后来者理解的演进路线——至于它最终叫单体还是微服务,其实没那么重要。