当你的系统从几十个接口长成几百个接口,当一个小改动牵动五六个模块,你会发现:
- 代码乱、逻辑乱、责任乱
- 团队协作成本高
- 业务快速演进受限
这时候,微服务和 DDD 就派上用场了。
微服务让系统“可拆、可扩展”,DDD 给拆分提供“业务指南针”。
本篇文章,我们用实战角度讲清楚:如何正确拆分微服务,以及如何用 DDD 定义服务边界。
第一部分:微服务拆分的挑战
-
随意拆分的后果
- 把 CRUD 随便拆服务 → 数据和逻辑分散,调用链长
- 服务之间强依赖 → 任何改动都可能触发连锁问题
- 服务数量激增 → 运维成本飙升
-
微服务拆分的关键问题
- 拆分依据是什么?
- 服务边界怎么定义?
- 聚合和上下文如何映射到服务?
没有业务指导的微服务拆分 = 灾难。
第二部分:DDD 指导下的服务拆分
DDD 提供了自然拆分微服务的方法:
-
按限界上下文(Bounded Context)拆
-
每个上下文就是一个独立服务
-
上下文内部逻辑一致,外部通过接口或事件通信
-
示例:
资产管理上下文 → AssetService 策略匹配上下文 → StrategyService 告警通知上下文 → AlertService
-
-
聚合内事务边界
- 聚合根是内部事务一致性的边界
- 一个聚合对应一个服务内部模块,不跨服务保证强事务
- 跨服务使用异步事件解决
-
领域事件驱动跨服务协作
-
上下文之间通过发布/订阅事件通信
-
例如:
AssetDiscovered → StrategyService 订阅 → 生成匹配结果 → AlertService 订阅 → 告警触发
-
第三部分:实战拆分步骤
步骤 1:识别核心业务领域
- 通过业务流程梳理,找出最重要的功能模块
- 优先拆分核心领域,外围辅助模块可慢慢迁移
步骤 2:定义限界上下文
- 每个上下文内部保持一致性
- 统一语言贯穿整个上下文
- 输出接口(API / 事件)对外提供能力
步骤 3:建立聚合与服务映射
- 每个聚合根对应服务内部模块
- 聚合内部保持事务一致性
- 聚合之间用事件通信
步骤 4:画微服务边界图
- 上下文 → 微服务
- 聚合 → 服务内部模块
- 事件 → 服务间通信线
示例图(ASCII) :
┌───────────┐ ┌────────────┐ ┌─────────────┐
│ AssetService │──▶│ StrategyService │──▶│ AlertService │
└───────────┘ └────────────┘ └─────────────┘
▲ ▲
│ │
聚合: Asset 聚合: Strategy
第四部分:微服务拆分注意事项
-
不要为了拆微服务而拆微服务
- 小团队或简单系统先用单体或模块化单体
-
核心领域优先
- 拆分最重要的业务领域,而非所有 CRUD
-
事件驱动解耦,避免强依赖
- 跨服务尽量异步通信
-
服务数量控制
- 拆太细 → 调用链长 → 运维复杂
- 拆太粗 → 微服务优势丧失
-
演进式拆分
- 逐步迁移,保证系统可用性
第五部分:总结
DDD 是微服务拆分的指南针,告诉你 按业务边界拆而不是按技术拆。
事件驱动是服务协作的神经系统,让微服务松耦合演化自如。
微服务拆分不是一次性任务,而是业务演进中的持续过程。