服务拆分策略
问题
微服务应该怎么拆?有哪些拆分原则?如何用 DDD 指导服务拆分?
答案
拆分原则
| 原则 | 说明 |
|---|---|
| 单一职责 | 每个服务只负责一个业务领域 |
| 高内聚低耦合 | 服务内部功能紧密相关,服务间依赖最少 |
| 独立数据 | 每个服务拥有自己的数据库,不共享 |
| 独立部署 | 修改一个服务不需要重新部署其他服务 |
| 团队对齐 | 一个团队负责一个或几个服务(Conway 定律) |
| 渐进拆分 | 从单体逐步拆分,不要一次性拆完 |
拆分维度
DDD 指导拆分
DDD(领域驱动设计)是微服务拆分的最佳理论指导。
| DDD 概念 | 微服务映射 | 说明 |
|---|---|---|
| 限界上下文 | 一个微服务 | 最重要的拆分依据 |
| 聚合根 | 服务内的核心实体 | 一个服务内管理一个或多个聚合 |
| 领域事件 | 服务间异步通信 | 通过 MQ 发布领域事件 |
| 上下文映射 | 服务间调用关系 | 防腐层、开放主机服务 |
拆分案例:电商单体 → 微服务
拆分粒度判断
拆分的度
太粗:服务依然庞大,失去微服务的敏捷性 太细:服务间调用过多,分布式事务频繁,网络开销大
判断标准:
- 一个服务是否只需 一个小团队(2~8 人) 维护
- 服务内的模块是否 经常一起变更
- 拆分后是否引入了 不必要的跨服务事务
常见面试问题
Q1: 服务拆分的依据是什么?
答案:
首选 业务领域(DDD 限界上下文) 作为拆分依据:
- 梳理业务流程,识别独立的业务领域(用户、商品、订单...)
- 每个领域成为一个微服务,拥有独立数据库
- 领域间通过 API 或事件通信
辅助依据:团队边界、变更频率、性能要求。
Q2: 拆分后服务间数据怎么处理?
答案:
- 各服务独立数据库:不直接访问其他服务的数据库
- API 查询:需要其他服务数据时通过 API 调用
- 数据冗余:将频繁查询的数据冗余存储到本服务(通过事件同步)
- CQRS:读写分离,查询模型可以聚合多个服务数据
Q3: 如何从单体渐进式拆分到微服务?
答案:
绞杀者模式(Strangler Fig Pattern):
- 新功能直接作为微服务开发
- 逐步将单体中的模块提取为独立服务
- 通过 API Gateway 路由:新请求走微服务,旧请求走单体
- 最终单体被完全替代