模块化单体到微服务:什么时候应该拆?

拆成多个服务后,每个服务可以独立发布,但本地调用也变成了可能超时的网络调用。先看独立扩容、团队协作或隔离需求是否真实存在,再决定是否拆分;仅仅目录多、代码多,并不足以支持这个决定。

版本与资料依据

  • last_verified: 2026-08-24
  • version_scope: stable architecture decision framework
  • source_type: architecture literature + engineering synthesis
  • stability: stable-concept
选择 判断条件 主要成本
Stay monolith 团队小、同一发布节奏、共享事务重要、运维能力有限 需控制耦合与构建规模
Modular monolith 业务边界可划分,但无需独立部署/扩缩;希望强制依赖 模块纪律、内部 API 与事件治理
Split service 明确团队所有权、独立部署/扩缩、数据所有权、故障隔离收益 网络失败、最终一致、平台、观察与安全成本

拆分前证据

  1. 模块 API 已稳定并有 contract tests;
  2. 该模块拥有数据,其他模块不直连其表;
  3. trace/metrics 证明独立扩缩或故障隔离有价值;
  4. 团队可运营 deploy、SLO、on-call、secret、migration;
  5. 事件/outbox/idempotency 已在单体内验证;
  6. 延迟与一致性变化得到业务接受。

“代码很多”不是充分理由。若拆分只增加 HTTP 而数据库仍共享,通常得到分布式单体。

用一个问题检验拆分收益

假设报表计算占用大量 CPU,拖慢了下单。先收集两类请求的耗时与资源使用,再比较进程内隔离、单独工作进程和独立服务三种方案。只有当独立部署或资源隔离的收益足够明确时,拆分才有可说明的理由。

还要做反向实验:报表服务断开后,下单能否继续?调用方等待多久?失败如何呈现?如果拆出服务以后每次下单仍同步等待它,原来的耦合可能只是变成了网络耦合。

本节的核验依据

2026-10-25 查阅。下面的链接支持本节的机制说明;练习场景和选型建议是本教程的教学设计。