服务建模是业务建模成果向服务架构的映射过程。
业务建模解决"业务世界如何被理解与结构化",服务建模在此之上解决:
识别出的业务边界,如何转化为可独立部署、演进和治理的服务单元?
服务建模不是重新发明业务模型,而是在业务模型的约束下做出服务设计决策。
软件系统的核心难题不是技术实现,而是对业务复杂性的承载与约束:
服务建模 = 对复杂性进行分区与封装的过程
微服务的本质不是"服务很多",而是边界清晰。
服务边界必须来自业务边界,而非技术边界:
业务认知在初期一定是不完整的,早期模型几乎必然是"错的":
好的服务建模不是一次性设计,而是允许被逐步修正的设计
先单体,后服务是理性选择——过早拆分会将不成熟的边界固化。
| 维度 | 描述 |
|---|---|
| 松耦合 | 服务对外部世界的认知越少越好,只依赖稳定契约 |
| 高内聚 | 一个服务只解决一类相关问题,行为围绕同一业务目标 |
高内聚是边界正确的结果,而非额外设计。
服务建模有三种切入方式,稳定性不同:
| 视角 | 稳定性 | 适用阶段 | 风险 |
|---|---|---|---|
| 业务能力 | 高 | 全周期 | 低 |
| 用例 | 中 | 初期探索 | 中 |
| 技术能力 | 低 | 特定场景 | 高 |
长期稳定的架构应以业务能力为核心。技术应服务于业务边界,而非反之。
业务建模中识别的语义边界(如 DDD 中的 Bounded Context)是服务边界划分的依据,但映射关系并非一对一:
| 场景 | 说明 |
|---|---|
| 1 个语义边界 → 1 个服务 | 理想状态 |
| 1 个语义边界 → N 个服务 | 演进或扩展阶段 |
| N 个语义边界 → 1 个服务 | 早期或过渡阶段 |
不要教条化"一对一"映射。语义边界是认知边界,服务边界是部署单元,两者粒度由当前阶段决定。
单一维度无法得出合理的拆分结论,需综合多个维度:
服务拆分维度
├─ 业务维度
│ ├─ 子域归属
│ ├─ 业务能力独立性
│
├─ 变化维度
│ ├─ 变更频率
│ ├─ 生命周期差异
│
├─ 非功能维度
│ ├─ 性能与扩展需求
│ ├─ 可靠性要求
│ ├─ 安全隔离需求
│
└─ 组织维度
├─ 团队边界对齐
└─ 责任归属清晰
服务内部结构的核心原则是保护业务核心不受外部技术污染:
六边形架构、整洁架构本质上都是这一原则的体现。
| 模式 | 适用场景 | 特点 |
|---|---|---|
| 事务脚本 | 简单业务 | 过程式、低成本 |
| 领域模型 | 复杂业务 | 状态与行为内聚、可演进 |
不要在简单系统中过度设计。领域模型的引入成本应与业务复杂度匹配。
业务模型中的一致性边界直接约束服务的事务设计:
架构设计的最高境界是避免跨边界事务,而非解决它。
跨服务协作是不同语义世界之间的翻译问题。
每个服务拥有自己的内部模型,跨服务调用必须通过明确定义的契约,而非直接访问对方的内部结构。
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 同步调用 | 强依赖、即时响应 | 查询、需要即时反馈的操作 |
| 异步事件 | 松耦合、最终一致 | 跨域状态同步、副作用传播 |
| Saga | 补偿式分布式事务 | 跨服务业务流程 |
异步事件是跨边界协作的首选——服务只需发布"已发生的事实",下游自主订阅,耦合最小。
过早拆分的代价:
演进路径:
单体验证业务模型 → 识别稳定边界 → 按边界逐步拆分
演进优于革命。重要的是每次拆分都基于已验证的业务边界。
Conway 定律揭示了服务建模与组织的深层关系:
系统结构是组织沟通结构的映射
这意味着:
服务边界的合理性,最终会体现在团队自治程度上。