首页/开发/系统分析与架构设计速查/模块化单体(Modular Monolith)
架构风格与模式58 条

模块化单体(Modular Monolith)

一个部署单元内按业务模块划分,模块之间通过显式接口通信并禁止跨模块访问内部实现;保留单体部署的简单性,同时获得清晰边界。

模块化单体是什么

模块化单体在单个部署单元内按业务子域划分模块,模块之间只能通过显式接口通信,禁止跨模块访问内部实现。它保留了单体在部署、调试、事务上的简单性,同时用编译期或构建期约束把边界固化下来,是走向服务化之前更稳妥的中间形态。

为什么值得先做

直接在单体上拆服务,往往会发现代码里根本没有清晰边界,只能按技术分层切开,结果得到一堆必须同步发布的分布式组件。先在单体内把模块边界与数据所有权理顺,拆分时才有真实存在的接缝可以下刀,回滚成本也低得多。

基本信息

边界手段模块接口、包结构约束、构建期依赖检查
数据单库,但按模块划分表的所有权
调用规则跨模块只能调用公开接口,内部实现不可见
演进价值边界稳定后可平滑演进为服务化

实践要点

  • 按子域划分模块,以业务能力命名,不按技术分层
  • 显式接口:模块只暴露接口包,内部实现包禁止外部引用
  • 构建期约束:接入依赖检查工具,违规引用直接让构建失败
  • 数据所有权:表归属单一模块,跨模块取数必须走接口
  • 接口兼容:模块接口变更走扩展-收缩,避免同步改多处
  • 演进路径:边界稳定后优先拆分读多写少、团队独立的模块

依赖检查工具

技术栈工具
JavaArchUnit
Pythonimport-linter
C# 与 .NETNetArchTest
JS 与 TSdependency-cruiser

与普通单体的差别

普通单体往往按技术分层组织代码,业务规则散落在控制器、服务与数据访问层里,改一个业务需求要动所有层。模块化单体按业务子域组织代码,一个子域的领域逻辑、接口与数据归属集中在一起,交付新需求通常只落在单个模块内。这个差别决定了它是通往服务化的跳板,还是又一个需要重构的遗留系统。

模块化单体的验收标准是:能否在不改动其他模块的前提下替换某个模块的实现。做不到这一点,说明边界还停留在目录命名上。

易错点

  • 模块间直接调用内部类,边界只停留在文档和目录结构上
  • 共用一张宽表,模块数据所有权不清,改表牵动多个模块
  • 只做包结构约定不接构建期检查,违规引用长期无人发现
  • 模块数量与团队职责不匹配,一个人维护十几个模块,边界形同虚设

数据来源与参考

  • Simon Brown 模块化单体相关文章
  • Sam Newman《Monolith to Microservices》(O'Reilly)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌