强曰为道

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

第 02 章:拆分原则

第 02 章:拆分原则

好的拆分让服务各司其职,差的拆分制造分布式噩梦。原则决定方向。


2.1 单一职责原则(SRP)

2.1.1 从面向对象到服务设计

单一职责原则(Single Responsibility Principle)源自 Robert C. Martin,原本指一个类应该只有一个引起它变化的原因。在微服务语境下,这个原则演化为:

一个微服务应该只负责一个业务能力(Business Capability)。

  ❌ 错误理解:按技术层拆分

  ┌──────────┐  ┌──────────┐  ┌──────────┐
  │ 前端服务  │  │ 后端服务  │  │ 数据服务  │
  └──────────┘  └──────────┘  └──────────┘
  (这不是微服务,这是分布式单体)

  ✅ 正确理解:按业务能力拆分

  ┌──────────┐  ┌──────────┐  ┌──────────┐
  │ 用户服务  │  │ 订单服务  │  │ 支付服务  │
  │ (前端+   │  │ (前端+   │  │ (前端+   │
  │  后端+DB) │  │  后端+DB) │  │  后端+DB) │
  └──────────┘  └──────────┘  └──────────┘

2.1.2 判断标准

如何判断一个服务是否承担了过多职责?

信号说明
服务名包含 “and”如 “OrderAndPaymentService” — 明显违反 SRP
修改一个功能需要改动多处说明职责耦合
服务的 API 超过 30 个可能需要进一步拆分
团队中不同人负责不同部分说明业务域不同
服务启动时间过长可能承载了过多功能

2.1.3 业务能力识别

业务能力(Business Capability)是组织为实现其目标所做的事情。识别业务能力的方法:

┌──────────────────────────────────────────────────┐
│              电商企业业务能力地图                    │
├──────────────────────────────────────────────────┤
│                                                  │
│  ┌────────────────┐    ┌────────────────┐       │
│  │   核心业务能力   │    │   支撑业务能力   │       │
│  ├────────────────┤    ├────────────────┤       │
│  │ • 用户管理      │    │ • 库存管理      │       │
│  │ • 商品管理      │    │ • 物流管理      │       │
│  │ • 订单管理      │    │ • 客服系统      │       │
│  │ • 支付处理      │    │ • 数据分析      │       │
│  │ • 营销活动      │    │ • 内容管理      │       │
│  └────────────────┘    └────────────────┘       │
│                                                  │
│  ┌────────────────┐    ┌────────────────┐       │
│  │   通用业务能力   │    │   管理业务能力   │       │
│  ├────────────────┤    ├────────────────┤       │
│  │ • 通知服务      │    │ • 权限管理      │       │
│  │ • 文件存储      │    │ • 审计日志      │       │
│  │ • 搜索服务      │    │ • 系统配置      │       │
│  └────────────────┘    └────────────────┘       │
└──────────────────────────────────────────────────┘

2.2 业务边界划分

2.2.1 高内聚、低耦合

服务内部的元素应该紧密相关(高内聚),服务之间的依赖应该尽可能少(低耦合)。

  高内聚 ✅                    低内聚 ❌
  ┌───────────────┐          ┌───────────────┐
  │   订单服务     │          │   订单服务     │
  │               │          │               │
  │ • 创建订单     │          │ • 创建订单     │
  │ • 取消订单     │          │ • 用户注册     │
  │ • 查询订单     │          │ • 商品搜索     │
  │ • 订单状态管理  │          │ • 支付处理     │
  │ • 订单金额计算  │          │ • 订单状态管理  │
  └───────────────┘          └───────────────┘
  (职责聚焦)                (什么都干)

2.2.2 边界识别方法

方法描述适用场景
业务流程分析梳理核心业务流程,识别独立的业务步骤流程驱动的系统
数据关系分析分析实体间关系密度,紧密耦合的实体归为一个服务数据密集型系统
变更频率分析变更频率相近的功能归为一组迭代频繁的系统
团队结构分析按团队职责划分服务边界组织结构清晰的场景
DDD 限界上下文使用领域驱动设计识别上下文边界复杂业务领域(详见第 03 章)

2.2.3 边界划分实例:在线教育平台

┌─────────────────────────────────────────────────────────┐
│                在线教育平台 - 服务划分                     │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │ 用户服务  │  │ 课程服务  │  │ 学习服务  │             │
│  ├──────────┤  ├──────────┤  ├──────────┤             │
│  │• 注册/登录│  │• 课程管理 │  │• 学习进度 │             │
│  │• 个人信息 │  │• 章节管理 │  │• 笔记管理 │             │
│  │• 学员认证 │  │• 课程分类 │  │• 作业提交 │             │
│  └──────────┘  └──────────┘  └──────────┘             │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │ 支付服务  │  │ 直播服务  │  │ 通知服务  │             │
│  ├──────────┤  ├──────────┤  ├──────────┤             │
│  │• 课程购买 │  │• 直播推流 │  │• 站内消息 │             │
│  │• 退款处理 │  │• 录播回放 │  │• 邮件通知 │             │
│  │• 订单管理 │  │• 互动弹幕 │  │• 短信通知 │             │
│  └──────────┘  └──────────┘  └──────────┘             │
└─────────────────────────────────────────────────────────┘

2.3 康威定律(Conway’s Law)

2.3.1 原文

“Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure.”

— Melvin Conway, 1967

翻译:设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。

2.3.2 康威定律在微服务中的应用

  组织结构                        系统架构

  ┌──────────┐                  ┌──────────┐
  │ 用户团队  │                  │ 用户服务  │
  │ (5人)    │──────────────────│          │
  └──────────┘                  └──────────┘

  ┌──────────┐                  ┌──────────┐
  │ 交易团队  │                  │ 订单服务  │
  │ (8人)    │──────────────────│ 支付服务  │
  └──────────┘                  └──────────┘

  ┌──────────┐                  ┌──────────┐
  │ 基础设施  │                  │ API 网关  │
  │ 团队(6人)│──────────────────│ 监控平台  │
  └──────────┘                  └──────────┘

2.3.3 逆康威定律(Inverse Conway Maneuver)

既然组织结构会影响系统架构,那么我们可以反过来——先设计理想的服务架构,再调整组织结构去匹配它。

  传统路径:组织结构 ──决定──▶ 系统架构
  逆向路径:理想架构 ──指导──▶ 组织调整

实践方法

  1. 设计目标微服务架构
  2. 按服务边界组建团队
  3. 每个团队对一个或几个服务端到端负责(You Build It, You Run It)
  4. 团队规模遵循 Two-Pizza Team(6-10 人)

2.3.4 团队拓扑(Team Topologies)

Matthew Skelton 和 Manuel Pais 在《Team Topologies》一书中提出了四种团队类型:

团队类型英文职责与其他团队的交互模式
流对齐团队Stream-aligned Team端到端交付业务价值主要团队类型
赋能团队Enabling Team帮助流对齐团队克服技术障碍协作模式
复杂子系统团队Complicated-subsystem Team管理需要专业技能的子系统X 即服务模式
平台团队Platform Team提供内部平台服务X 即服务模式
  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
  │ 用户流团队    │  │ 交易流团队    │  │ 内容流团队    │
  │ (Stream)     │  │ (Stream)     │  │ (Stream)     │
  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘
         │                 │                 │
         ▼                 ▼                 ▼
  ┌──────────────────────────────────────────────────┐
  │              平台团队 (Platform)                   │
  │  CI/CD · K8s · 监控 · 日志 · 服务发现              │
  └──────────────────────────────────────────────────┘

2.4 共享与独立的权衡

2.4.1 可以共享的部分

共享内容是否推荐说明
共享代码库❌ 不推荐造成强耦合,独立演进困难
共享数据库❌ 不推荐违反数据自治原则
共享库(Library)✅ 推荐通用工具库、SDK 可以共享
共享基础设施✅ 推荐K8s 集群、监控、日志平台
共享 API 契约✅ 推荐API Schema、Protocol Buffers

2.4.2 应该独立的部分

  每个服务应该独立拥有:

  ┌─────────────────────────────────────┐
  │            微服务                    │
  │                                     │
  │  ┌─────────────────────────────┐   │
  │  │  独立代码库 (Git Repo)       │   │
  │  ├─────────────────────────────┤   │
  │  │  独立数据库 (Schema/实例)    │   │
  │  ├─────────────────────────────┤   │
  │  │  独立 CI/CD Pipeline        │   │
  │  ├─────────────────────────────┤   │
  │  │  独立部署 (独立进程)         │   │
  │  ├─────────────────────────────┤   │
  │  │  独立监控和告警              │   │
  │  ├─────────────────────────────┤   │
  │  │  独立团队负责                │   │
  │  └─────────────────────────────┘   │
  └─────────────────────────────────────┘

2.5 拆分粒度的把控

2.5.1 粒度评估维度

维度过粗(需要拆分)适中过细(需要合并)
代码量> 5 万行1-3 万行< 1000 行
API 数量> 50 个10-30 个< 5 个
团队人数> 15 人5-10 人1-2 人
部署频率月级日/周级极少部署
数据表> 50 张10-20 张1-2 张

2.5.2 纳米服务反模式(Nanoservice Anti-pattern)

  ❌ 纳米服务:拆得过细

  ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
  │创│ │验│ │计│ │扣│ │退│ │查│ │取│ │删│
  │建│ │证│ │算│ │减│ │款│ │询│ │消│ │除│
  │订│ │订│ │金│ │库│ │处│ │订│ │订│ │订│
  │单│ │单│ │额│ │存│ │理│ │单│ │单│ │单│
  └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘
  (每个"服务"只有一个函数,运维成本远超收益)

  ✅ 合理粒度

  ┌──────────────────┐  ┌──────────────────┐
  │     订单服务      │  │     库存服务      │
  │                  │  │                  │
  │ • 创建/取消订单   │  │ • 库存扣减/恢复   │
  │ • 订单查询        │  │ • 库存查询        │
  │ • 金额计算        │  │ • 库存预警        │
  │ • 退款处理        │  │                  │
  └──────────────────┘  └──────────────────┘

2.5.3 “大泥球"识别清单

以下特征表明服务可能需要进一步拆分:

  • 服务中有 3 个以上不相关的业务模块
  • 不同功能的变更频率差异很大
  • 一个功能的 bug 可能影响其他功能
  • 团队内部出现"子团队”
  • 部署一个功能需要回归测试所有功能

2.6 拆分原则总结

2.6.1 核心原则清单

#原则说明
1单一职责一个服务只负责一个业务能力
2高内聚服务内部元素紧密关联
3低耦合服务之间依赖最小化
4数据自治每个服务拥有自己的数据
5团队自治团队对服务端到端负责
6技术自治服务可独立选择技术栈
7部署自治服务可独立部署和扩缩容
8故障隔离单个服务故障不影响全局

2.6.2 拆分检查清单

在决定拆分一个服务前,逐一检查:

  ┌─ 是否有明确的业务边界?
  │
  ├─ 是否有独立的数据模型?
  │
  ├─ 是否有独立的团队负责?
  │
  ├─ 是否有不同的扩展需求?
  │
  ├─ 是否有不同的变更频率?
  │
  ├─ 基础设施是否就绪(CI/CD、监控)?
  │
  └─ 拆分的收益是否大于成本?
     │
     ├─ 全部 "是" → 果断拆分
     ├─ 大部分 "是" → 规划后拆分
     └─ 多数 "否" → 暂不拆分

2.7 业务场景:SaaS 系统的拆分决策

背景:一个企业级 SaaS 项目管理工具,包含项目管理、任务管理、文档协作、团队沟通、报表统计五个模块。

分析过程

模块业务边界数据独立性变更频率扩展需求拆分决策
项目管理✅ 清晰✅ 项目、成员🟡 中🟡 中暂不拆分
任务管理✅ 清晰✅ 任务、看板🔴 高🔴 高优先拆分
文档协作✅ 清晰✅ 文档、版本🟡 中🔴 高(存储)第二优先
团队沟通✅ 清晰✅ 消息、频道🔴 高🔴 高(实时)第一优先
报表统计✅ 清晰✅ 聚合数据🟢 低🟡 中后期拆分

拆分顺序:团队沟通(实时性要求最高)→ 任务管理(变更最频繁)→ 文档协作(存储扩展需求)→ 报表统计


⚠️ 注意事项

  1. 不要追求完美划分——边界会随着业务理解的深入而演进
  2. 避免循环依赖——服务间出现 A→B→C→A 的循环是危险信号
  3. 警惕共享数据库——如果两个服务必须共享数据库,说明它们可能应该是同一个服务
  4. 考虑事务边界——需要强事务的功能尽量在同一个服务内
  5. 命名很重要——好的服务名称(如 OrderService)能清晰传达职责

📖 扩展阅读

  1. Conway’s Law — Martin Fowler 的详细解释(martinfowler.com/articles/conways-law.html)
  2. Team Topologies — Matthew Skelton, Manuel Pais — 团队结构与软件架构的关系
  3. Domain-Driven Design — Eric Evans — 用 DDD 指导服务边界的划分(详见第 03 章)
  4. The Art of Scalability — Martin Abbott — 可扩展性的系统方法论
  5. Building Microservices — Sam Newman, Chapter 2: The Evolutionary Architect

本章小结

要点说明
单一职责一个服务 = 一个业务能力
业务边界高内聚、低耦合是划分的黄金法则
康威定律组织结构 ≈ 系统架构,用逆康威定律指导组织设计
粒度把控避免纳米服务,从粗粒度开始逐步细化
决策依据业务边界 + 数据独立性 + 变更频率 + 团队结构

📌 下一章第 03 章:领域驱动设计 — 用 DDD 的方法论科学地识别服务边界。