强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

微服务拆分精讲 / 第 04 章:拆分策略

第 04 章:拆分策略

策略决定路径。选对拆分策略,事半功倍;选错策略,步步艰难。


4.1 拆分策略总览

4.1.1 四种核心策略

┌─────────────────────────────────────────────────────────┐
│                   微服务拆分策略矩阵                      │
├─────────────────────────────────────────────────────────┤
│                                                         │
│           ┌───────────┐        ┌───────────┐           │
│           │ 按业务能力 │        │ 按子域拆分  │           │
│           │ (Business  │        │ (Subdomain │           │
│           │ Capability)│        │  Based)    │           │
│           └───────────┘        └───────────┘           │
│                  ▲                    ▲                 │
│                  │    拆分策略         │                 │
│                  │                    │                 │
│           ┌───────────┐        ┌───────────┐           │
│           │ 按团队结构 │        │ 渐进式拆分  │           │
│           │ (Team     │        │ (Strangler │           │
│           │  Based)   │        │  Pattern)  │           │
│           └───────────┘        └───────────┘           │
└─────────────────────────────────────────────────────────┘

4.1.2 策略选择指南

策略适用场景优势风险
按业务能力业务领域成熟、边界清晰拆分后稳定性高前期分析工作量大
按子域(DDD)复杂业务、多个限界上下文科学严谨需要 DDD 经验
按团队结构组织架构清晰执行阻力小可能不最优
渐进式(绞杀者)大型遗留系统风险最低周期长

4.2 策略一:按业务能力拆分(Business Capability Split)

4.2.1 核心思路

将系统按照组织的业务能力(Business Capability)进行拆分。业务能力是组织为实现商业目标所做的事情。

┌──────────────────────────────────────────────────┐
│              保险公司的业务能力                     │
├──────────────────────────────────────────────────┤
│                                                  │
│  ┌──────────────┐    ┌──────────────┐           │
│  │   产品管理    │    │   核保管理    │           │
│  │  · 产品设计   │    │  · 风险评估   │           │
│  │  · 费率计算   │    │  · 核保规则   │           │
│  │  · 产品上下架 │    │  · 人工审核   │           │
│  └──────────────┘    └──────────────┘           │
│                                                  │
│  ┌──────────────┐    ┌──────────────┐           │
│  │   投保管理    │    │   理赔管理    │           │
│  │  · 投保申请   │    │  · 理赔报案   │           │
│  │  · 保单生成   │    │  · 定损核赔   │           │
│  │  · 保单变更   │    │  · 赔款支付   │           │
│  └──────────────┘    └──────────────┘           │
│                                                  │
│  ┌──────────────┐    ┌──────────────┐           │
│  │   客户管理    │    │   财务管理    │           │
│  │  · 客户信息   │    │  · 收费管理   │           │
│  │  · 客户画像   │    │  · 佣金计算   │           │
│  └──────────────┘    └──────────────┘           │
└──────────────────────────────────────────────────┘

4.2.2 操作步骤

步骤活动输出
1梳理组织的核心业务能力业务能力地图
2评估每个能力的独立性依赖关系图
3识别共享能力(如通知、认证)共享服务清单
4按业务能力划分服务服务划分方案
5为每个服务分配团队团队-服务映射

4.2.3 案例:在线教育平台

  业务能力                     对应服务
  ────────                    ────────
  用户注册/认证         ──▶    用户服务
  课程管理/发布         ──▶    课程服务
  视频播放/直播         ──▶    媒体服务
  学习进度跟踪          ──▶    学习服务
  考试/作业批改         ──▶    评测服务
  订单/支付             ──▶    交易服务
  消息通知              ──▶    通知服务

4.3 策略二:按 DDD 子域拆分

4.3.1 核心子域 vs 支撑子域 vs 通用子域

DDD 将业务领域划分为三种子域类型:

子域类型英文特征投入策略示例
核心子域Core Domain业务核心竞争力重投入,自研电商的推荐算法
支撑子域Supporting Domain辅助核心业务适度投入电商的库存管理
通用子域Generic Domain通用能力尽量外购/复用用户认证、支付
┌────────────────────────────────────────────────────┐
│                  电商领域子域划分                     │
├────────────────────────────────────────────────────┤
│                                                    │
│  ┌─────────────────────────────────────────────┐  │
│  │               核心子域 (Core)                │  │
│  │                                             │  │
│  │   ┌─────────┐  ┌─────────┐  ┌─────────┐   │  │
│  │   │ 搜索推荐 │  │ 价格引擎 │  │ 会员体系 │   │  │
│  │   └─────────┘  └─────────┘  └─────────┘   │  │
│  └─────────────────────────────────────────────┘  │
│                                                    │
│  ┌─────────────────────────────────────────────┐  │
│  │              支撑子域 (Supporting)            │  │
│  │                                             │  │
│  │   ┌─────────┐  ┌─────────┐  ┌─────────┐   │  │
│  │   │ 库存管理 │  │ 物流管理 │  │ 内容管理 │   │  │
│  │   └─────────┘  └─────────┘  └─────────┘   │  │
│  └─────────────────────────────────────────────┘  │
│                                                    │
│  ┌─────────────────────────────────────────────┐  │
│  │               通用子域 (Generic)              │  │
│  │                                             │  │
│  │   ┌─────────┐  ┌─────────┐  ┌─────────┐   │  │
│  │   │ 用户认证 │  │ 支付网关 │  │ 消息通知 │   │  │
│  │   └─────────┘  └─────────┘  └─────────┘   │  │
│  └─────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────┘

4.3.2 子域拆分的核心子域优先原则

  拆分顺序推荐:

  第 1 步:识别核心子域
         (业务价值最高的部分先拆分)
              │
              ▼
  第 2 步:拆分通用子域
         (认证、通知等通用能力独立出来)
              │
              ▼
  第 3 步:拆分支撑子域
         (根据依赖关系逐步拆分)
              │
              ▼
  第 4 步:优化和调整
         (根据运行情况微调边界)

4.4 策略三:按团队结构拆分

4.4.1 康威定律的应用

  当前团队结构:                    目标服务架构:

  ┌──────────┐                    ┌──────────┐
  │ A 团队    │  负责用户相关      │ 用户服务  │
  │ (6人)    │───────────────────▶│ 认证服务  │
  └──────────┘                    └──────────┘

  ┌──────────┐                    ┌──────────┐
  │ B 团队    │  负责交易相关      │ 订单服务  │
  │ (8人)    │───────────────────▶│ 支付服务  │
  └──────────┘                    └──────────┘

  ┌──────────┐                    ┌──────────┐
  │ C 团队    │  负责商品相关      │ 商品服务  │
  │ (6人)    │───────────────────▶│ 库存服务  │
  └──────────┘                    └──────────┘

  ┌──────────┐                    ┌──────────┐
  │ D 团队    │  负责基础设施      │ API 网关  │
  │ (5人)    │───────────────────▶│ 监控平台  │
  └──────────┘                    └──────────┘

4.4.2 团队拆分的原则

原则说明
Two-Pizza Team每个团队 6-10 人
端到端负责团队拥有服务的开发、测试、部署、运维
减少跨团队依赖一个需求尽量在一个团队内完成
共享平台团队平台/基础设施团队为业务团队提供底层支持

4.5 策略四:渐进式拆分(Strangler Fig Pattern)

4.5.1 绞杀者模式

绞杀者模式(Strangler Fig Pattern)得名于热带雨林中的绞杀榕——榕树从上方生长,逐渐包裹并取代宿主树。在软件中,新服务逐步替代旧系统的功能,直到旧系统完全被取代。

  阶段 1:路由层拦截
  ─────────────────────────────────────

  请求 ──▶ ┌──────────┐
           │ 路由层    │
           │          ├──▶ 旧系统 (全部请求)
           └──────────┘


  阶段 2:部分迁移
  ─────────────────────────────────────

  请求 ──▶ ┌──────────┐
           │ 路由层    │
           │          ├──▶ 旧系统 (80% 请求)
           │          ├──▶ 新服务A (10% 请求)
           │          └──▶ 新服务B (10% 请求)
           └──────────┘


  阶段 3:大部分迁移
  ─────────────────────────────────────

  请求 ──▶ ┌──────────┐
           │ 路由层    │
           │          ├──▶ 旧系统 (20% 请求)
           │          ├──▶ 新服务A (40% 请求)
           │          ├──▶ 新服务B (30% 请求)
           │          └──▶ 新服务C (10% 请求)
           └──────────┘


  阶段 4:完全迁移
  ─────────────────────────────────────

  请求 ──▶ ┌──────────┐
           │ API 网关  │
           │          ├──▶ 新服务A
           │          ├──▶ 新服务B
           │          ├──▶ 新服务C
           │          └──▶ 新服务D
           └──────────┘
           (旧系统已完全退役)

4.5.2 渐进式拆分的详细步骤

阶段活动持续时间产出
评估分析单体架构、识别业务边界2-4 周架构评估报告
规划确定拆分顺序、制定路线图1-2 周拆分路线图
准备搭建基础设施(CI/CD、监控等)2-4 周基础设施就绪
试点选择低风险模块进行试点拆分4-8 周第一个微服务
推广按路线图逐步拆分更多服务持续逐步增长的微服务
退役完全下线旧系统视规模而定纯微服务架构

4.5.3 选择试点服务的标准

  理想的试点服务应该:

  ✅ 业务边界清晰(容易识别输入输出)
  ✅ 依赖较少(不依赖太多其他模块)
  ✅ 风险较低(即使出问题也不影响核心业务)
  ✅ 有代表性(拆分经验可复用到其他模块)
  ✅ 变更频繁(拆分后收益明显)

  推荐的试点候选:
  ┌──────────────┬──────────┬──────────┬──────────┐
  │ 模块         │ 边界清晰 │ 依赖较少 │ 风险较低 │
  ├──────────────┼──────────┼──────────┼──────────┤
  │ 用户认证     │   ✅     │   ✅     │   ✅     │ ← 最佳候选
  │ 消息通知     │   ✅     │   ✅     │   ✅     │ ← 最佳候选
  │ 文件上传     │   ✅     │   ✅     │   ✅     │ ← 最佳候选
  │ 订单管理     │   ✅     │   ❌     │   ❌     │   复杂,后期拆
  │ 核心交易     │   ❌     │   ❌     │   ❌     │   最后拆
  └──────────────┴──────────┴──────────┴──────────┘

4.6 拆分的技术手段

4.6.1 代码层面的拆分

  拆分前:单体代码结构
  ─────────────────────
  monolith/
  ├── src/
  │   ├── user/          ← 用户模块
  │   ├── order/         ← 订单模块
  │   ├── product/       ← 商品模块
  │   └── payment/       ← 支付模块
  └── pom.xml            ← 单个构建文件


  拆分后:模块化单体 → 微服务
  ───────────────────────────

  阶段1:Maven Module 划分
  monolith/
  ├── user-module/       ← 独立模块
  ├── order-module/      ← 独立模块
  ├── product-module/    ← 独立模块
  └── pom.xml            ← 父 POM

  阶段2:提取为独立服务
  user-service/          ← 独立仓库、独立部署
  ├── src/
  ├── Dockerfile
  └── pom.xml

  order-service/         ← 独立仓库、独立部署
  ├── src/
  ├── Dockerfile
  └── pom.xml

4.6.2 数据层面的拆分

阶段方法说明
1. 逻辑分离同一数据库,不同 Schema最小改动,验证边界
2. 读写分离服务通过 API 读取其他服务数据减少直接数据库访问
3. 物理分离独立数据库实例完全数据自治
  阶段1:逻辑分离
  ┌─────────────────────────────┐
  │         单个数据库            │
  │  ┌────────┐  ┌────────┐    │
  │  │ user   │  │ order  │    │
  │  │ schema │  │ schema │    │
  │  └────────┘  └────────┘    │
  └─────────────────────────────┘

  阶段2:物理分离
  ┌──────────┐    ┌──────────┐
  │ 用户 DB   │    │ 订单 DB   │
  │ (独立实例) │    │ (独立实例) │
  └──────────┘    └──────────┘

4.7 拆分路线图模板

┌────────────────────────────────────────────────────────────────┐
│                    微服务拆分路线图 (示例)                       │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Q1 (第1-3月)                                                  │
│  ├── 第1-2周:架构评估、业务边界梳理                             │
│  ├── 第3-4周:基础设施搭建(CI/CD、监控、日志)                   │
│  ├── 第5-8周:试点拆分 - 用户服务                                │
│  └── 第9-12周:试点拆分 - 认证服务                               │
│                                                                │
│  Q2 (第4-6月)                                                  │
│  ├── 第13-16周:拆分商品服务                                     │
│  ├── 第17-20周:拆分库存服务                                     │
│  └── 第21-24周:拆分通知服务                                     │
│                                                                │
│  Q3 (第7-9月)                                                  │
│  ├── 第25-28周:拆分订单服务(核心)                              │
│  ├── 第29-32周:拆分支付服务                                     │
│  └── 第33-36周:拆分物流服务                                     │
│                                                                │
│  Q4 (第10-12月)                                                │
│  ├── 第37-40周:拆分推荐/搜索服务                                │
│  ├── 第41-44周:旧系统下线                                       │
│  └── 第45-48周:优化、文档、复盘                                 │
└────────────────────────────────────────────────────────────────┘

4.8 业务场景:金融系统的拆分策略

背景:一个银行核心系统,包含账户管理、转账汇款、贷款管理、信用卡、理财五大模块。系统运行 10 年,代码 300 万行。

策略选择:渐进式拆分(绞杀者模式),原因:

  • 系统运行年限长,代码耦合严重
  • 金融系统对稳定性要求极高
  • 不允许停服迁移

拆分顺序

顺序模块策略理由
1通知服务低风险试点无资金操作,失败影响小
2理财服务业务独立相对独立的业务线
3信用卡服务子域拆分独立的产品线
4贷款服务子域拆分独立的产品线
5转账汇款核心最后拆涉及核心资金流
6账户管理核心最后拆所有服务的基础

⚠️ 注意事项

  1. 不要大爆炸式重写——永远不要停止维护旧系统去重写新系统
  2. 保持双写过渡期——迁移期间新旧系统共存,通过数据同步保持一致
  3. 自动化先行——没有 CI/CD 和自动化测试,拆分风险极高
  4. 数据迁移是难点——代码拆分容易,数据拆分是最复杂的部分
  5. 回滚计划——每个拆分步骤都要有回滚方案

📖 扩展阅读

  1. Martin Fowler - Strangler Fig Application — 绞杀者模式的权威描述
  2. Sam Newman - Monolith to Microservices — 从单体到微服务的迁移模式
  3. Chris Richardson - Pattern: Strangler Fig — 绞杀者模式的详细实现
  4. ThoughtWorks - Evolutionary Architecture — 演进式架构方法论
  5. Fundamentals of Software Architecture — Mark Richards, Neal Ford

本章小结

策略核心思路最佳适用
按业务能力按组织业务能力划分业务成熟的组织
按 DDD 子域按核心/支撑/通用子域划分复杂业务系统
按团队结构按团队职责划分组织结构清晰
渐进式拆分绞杀者模式逐步替换大型遗留系统

📌 下一章第 05 章:数据库拆分 — 微服务拆分中最难的部分:如何拆分数据库。