第二十一课:系统是怎么一步步拆坏的?——单体到模块化实践(完整工程版)

在很多技术文章里,"微服务"往往被描述为高级架构的象征。

但真实工程中,绝大多数系统不是被写崩的,而是被拆崩的。

这篇文章不讲"怎么拆系统",

而是先讲一个更重要的问题:

系统是怎么被一步步拆坏的?

因为在你学会"拆"之前,必须先学会"合"。

一、单体系统不是贬义词

很多新人一听"单体",就觉得是落后的架构。

其实不是。

单体系统 = 一个工程 + 一个部署包 + 一个数据库

优点非常明显:

  • 架构简单
  • 调试方便
  • 性能高
  • 运维成本低
  • 部署极快

在中小规模业务阶段,
单体往往是最优解,而不是过渡方案。

问题只在于:

  • 团队规模扩大
  • 功能复杂度增加
  • 协作冲突变多
  • 发布风险变高

这时才需要"演进",而不是"一刀切拆分"。

二、系统是如何被"拆坏"的?

1. 过早微服务

业务刚起步,用户没几个,

却一口气拆出 10 个服务。

结果:

  • 运维复杂度暴涨
  • 服务调用链路复杂
  • 故障难排查
  • 成本远超收益

本质问题:
复杂度先于业务规模出现。

2. 过度拆分

把一个完整业务拆成无数小服务:

  • 登录服务
  • 昵称服务
  • 头像服务
  • 密码服务

结果:

  • 网络调用爆炸
  • 延迟增加
  • 服务依赖成蜘蛛网
  • 性能下降

拆分不是粒度越细越好,而是边界清晰才好

3. 服务边界不清

最危险的一种:

复制代码
A → B → C → A

出现循环依赖后:

  • 调用链路无法理解
  • 故障传播范围扩大
  • 调试难度指数级上升

4. 数据库乱拆

数据库被随意分库:

  • 强事务业务被拆
  • 跨库查询复杂
  • 一致性难保证

数据层一旦拆错,

修复成本远高于代码层。

三、正确的系统演进路径

系统演进不是:

复制代码
单体 → 微服务

而是:

复制代码
单体
 ↓
模块化单体
 ↓
少量核心服务拆分
 ↓
微服务治理

关键点在第二步:模块化单体

四、什么是模块化单体?

模块化单体的本质:

在一个工程中,把未来的服务边界提前划清。

示意结构:

复制代码
project
 ├─ user
 ├─ order
 ├─ payment
 ├─ common
 └─ api

特点:

  • 一个部署包
  • 一个数据库
  • 模块之间高内聚低耦合
  • 内部调用为主

优点:

  • 成本极低
  • 结构清晰
  • 随时可拆
  • 无运维负担

模块化单体做得好,

未来微服务就像"拆积木"。

五、模块内部结构:Domain / Biz / Repository

模块清晰只是第一步,

模块内部同样要清晰。

典型结构:

复制代码
order
 ├─ domain
 ├─ biz
 ├─ repository
 ├─ dto
 └─ api

1. Domain(领域层)

负责业务规则:

  • 状态流转
  • 金额计算
  • 校验逻辑
  • 实体定义

特点:

  • 稳定
  • 高内聚
  • 无技术依赖

一句话:

Domain 管"规则"。

2. Biz(业务层)

负责流程编排:

  • 串联多个 Domain
  • 控制事务
  • 发 MQ
  • 调 RPC

特点:

  • 经常改
  • 技术依赖多
  • 不稳定

一句话:

Biz 管"流程"。

3. Repository(数据层)

负责数据库交互:

  • 查询
  • 保存
  • 隔离 SQL

口诀:

Domain 不碰数据库,Repository 专门干脏活。

4. DTO / VO(边界模型)

负责接口层数据:

  • 输入输出
  • 避免领域对象污染

口诀:

领域对象不出门,接口对象不进门。

六、依赖方向控制(模块化的生命线)

模块划分不等于模块清晰,
依赖方向才是真正的生命线。

原则:

  • 业务模块可以依赖 common
  • common 不能依赖业务模块
  • 禁止双向依赖
  • 禁止循环依赖

一旦出现双向依赖,

模块会迅速退化成"伪模块"。

关键词可以记住:

  • 依赖倒置
  • 接口隔离
  • 防止循环依赖

七、common 模块的三大陷阱

很多项目最终死在:

复制代码
common
 ├─ util
 ├─ helper
 ├─ tool
 ├─ xxx

变成"垃圾桶模块"。

正确原则:

common 只放"无业务语义"的纯工具能力。

例如:

  • 时间工具
  • 字符串工具
  • 基础配置

绝不能放:

  • 订单逻辑
  • 用户逻辑
  • 支付逻辑

否则未来拆服务会被它拖死。

八、什么时候才该拆服务?

拆服务的标准不是"代码多",而是以下条件之一:

条件 是否适合拆
并发极高 适合
独立部署需求 适合
团队独立开发 适合
强一致事务 不适合
强耦合业务 不适合

优先拆的天然独立模块:

  • 用户中心
  • 支付
  • 文件服务
  • 消息服务

九、模块化单体如何过渡到微服务?

模块化单体不是终点,

而是"可演进的起点"。

当某个模块出现:

  • 独立部署需求
  • 高并发压力
  • 独立团队维护
  • 技术栈差异

它就是天然的微服务候选。

这时拆分的成本极低,

因为边界早已清晰。

十、这一课真正培养的能力

不是画架构图,

而是三种判断力:

  1. 规模判断力 ------ 业务体量是否支撑复杂架构

  2. 边界判断力 ------ 哪些模块可以独立

  3. 成本判断力 ------ 运维复杂度是否值得

系统不是越高级越好,

而是越合适越好。

十一、总结口诀(工程记忆版)

可以记住这四句:

先模块化,再微服务。
先做清晰,再做复杂。
能不拆,就别拆。
系统不是高级,而是可演进。

系统的本质不是炫技,

而是 可理解、可维护、可扩展、可演进。

相关推荐
wanderful_1 小时前
自定义用户体系下 Django 业务模块开发踩坑与通用解决方案(技术分享版)
后端·python·django
Coder_Boy_1 小时前
Java高级_资深_架构岗 核心知识点(云原生)
java·云原生·架构
Coder_Boy_2 小时前
Java高级_资深_架构岗 核心面试知识点(AI整合+混合部署)
java·人工智能·spring boot·后端·面试·架构
阿钱真强道2 小时前
14 ThingsBoard实战:从零搭建设备配置+设备,完成MQTT温湿度上行/目标温度下行测试(对比JetLinks)
java·网络·python·网络协议
PD我是你的真爱粉2 小时前
RabbitMQRPC与死信队列
后端·python·中间件
乘风gg2 小时前
企业级 Prompt 工程实战指南(下):构建可复用 Prompt 架构平台
前端·面试·架构
知识即是力量ol2 小时前
口语八股:MySQL 核心原理系列(二):事务与锁篇
java·数据库·mysql·事务·八股·原理·
BingoGo2 小时前
PHP 的问题不在语言本身,而在我们怎么写它
后端·php
X54先生(人文科技)2 小时前
20260212_Meta-CreationPower_Development_Log(启蒙灯塔起源团队开发日志)
人工智能·机器学习·架构·团队开发·零知识证明