3、微服务拆分原则:按业务能力拆分与按子域拆分

好,咱们今天聊点实在的。

微服务拆分,说白了就是「怎么切」的问题。切得好,系统灵活、团队高效;切得不好,那就是分布式灾难。我见过太多团队,一上来就按技术层拆——前端拆一个、后端拆一个、数据库再拆一个……结果呢?改一个需求要协调三个团队,发布一次像过年。

我个人习惯,拆服务只有两个靠谱的维度:按业务能力按子域。这两个不是二选一,而是相辅相成。

3.1 按业务能力拆分:从「用户视角」切

什么叫业务能力?就是用户能感知到的、完整的业务功能。

举个例子,一个传统ERP系统里,「订单管理」就是一项业务能力。用户能创建订单、修改订单、查询订单、取消订单。这些操作背后可能涉及库存、财务、物流,但对外暴露的,就是一个完整的「订单服务」。

按业务能力拆分,就是把这些「能力」拎出来,每个能力一个服务。

核心原则:每个服务应该对应一个完整的业务用例,而不是一个技术模块。

我在项目中遇到过一家制造企业,他们原来的ERP是单体架构。订单模块里混着库存查询、价格计算、甚至客户信用检查。拆的时候,我们先把「订单管理」单独拎出来,然后发现——订单创建时需要校验库存,库存查询又依赖仓库数据……嗯,这里要注意,业务能力不是凭空定义的,它需要你真正理解业务流程

按业务能力拆分的优点很明显:

  • 团队自治:每个服务由一个小团队全权负责,从设计到上线
  • 独立部署:改订单服务不影响库存服务
  • 技术异构:订单服务用Java,库存服务用Go,完全没问题

但缺点也有——粒度不好把握。拆得太粗,还是大泥球;拆得太细,服务间调用像蜘蛛网。

我的经验:刚开始拆的时候,宁可粗一点。一个服务包含3-5个相关功能,比拆成10个微型服务好管理得多。等业务稳定了,再考虑进一步拆分。

3.2 按子域拆分:从「业务模型」切

按子域拆分,是DDD(领域驱动设计)的核心思想。说白了,就是先画出业务的全景图,然后找到「边界」。

每个子域,对应一个独立的业务模型。比如ERP系统里:

  • 核心域:订单、库存、财务——这是赚钱的命根子
  • 支撑域:用户管理、权限控制——没有不行,但不是核心
  • 通用域:邮件通知、日志记录——直接买现成的

按子域拆分,就是把这些「域」变成服务。每个服务有自己的数据库、自己的业务逻辑、自己的团队。

关键区别:按业务能力拆分是「用户看到的」,按子域拆分是「业务模型里的」。前者偏功能,后者偏概念。

我曾经帮一个零售企业重构ERP。他们原来的系统里,「商品」和「库存」是混在一起的。商品信息里存着库存数量,库存表里又存着商品名称。拆的时候,我们按子域重新划分:

  • 商品子域:商品基本信息、分类、属性
  • 库存子域:库存数量、出入库记录、仓库管理
  • 价格子域:定价策略、促销规则、折扣计算

每个子域独立成服务,数据完全解耦。商品服务不知道库存有多少,库存服务也不关心商品叫什么。它们通过事件或API通信。

避坑指南:我曾经犯过一个错误——把「订单」和「支付」拆成两个子域,但没定义清楚边界。结果订单服务里偷偷存了支付状态,支付服务又存了订单金额。数据不一致,查问题查了三天。记住:子域之间不能共享数据库,只能通过接口通信

3.3 两种拆分方式的对比

维度 按业务能力拆分 按子域拆分
视角 用户/功能 业务模型/概念
粒度 偏粗,一个服务对应一个用例 偏细,一个服务对应一个领域
团队组织 按功能团队 按领域团队
适用场景 快速迭代、MVP阶段 复杂业务、长期维护
学习成本 低,业务人员也能理解 高,需要DDD基础

你想想看,这两种方式其实不冲突。我通常的做法是:先用业务能力拆分快速落地,再用子域拆分逐步优化

3.4 实战:一个ERP系统的拆分案例

假设我们要重构一个传统ERP系统。原来的模块有:采购、销售、库存、财务、人力资源、生产管理。

按业务能力拆分,我们得到:

  • 采购服务
  • 销售服务
  • 库存服务
  • 财务服务
  • 人力资源服务
  • 生产管理服务

每个服务独立部署,独立数据库。看起来不错,对吧?

但运行半年后,问题来了:

  • 「销售服务」里混着客户信用检查(应该属于财务)
  • 「采购服务」里混着供应商评价(应该属于人力资源)
  • 「生产管理服务」里混着物料需求计算(应该属于库存)

这就是按业务能力拆分的局限性——业务能力之间天然有交叉

于是我们引入子域拆分,重新梳理:

  • 客户子域:客户信息、信用等级、合同管理
  • 供应商子域:供应商信息、评价、资质
  • 物料子域:物料清单、BOM、物料需求
  • 财务子域:应收应付、总账、成本核算

然后,每个子域对应一个服务。原来的「销售服务」被拆成「客户服务」+「订单服务」+「价格服务」。原来的「采购服务」被拆成「供应商服务」+「采购订单服务」+「收货服务」。

最终结果:服务数量从6个变成了12个,但每个服务的职责更清晰,变更影响范围更小。团队也从「按功能分组」变成了「按领域分组」,每个团队只关心自己的业务模型。

3.5 我的建议:先粗后细,逐步演进

如果你问我,微服务拆分有没有标准答案?

没有。

但我可以给你一个可操作的路径:

  1. 第一步:按业务能力拆。画出用户能感知的所有功能,每个功能一个服务。别想太多,先跑起来。
  2. 第二步:识别子域。运行一段时间后,观察哪些服务经常一起变更,哪些数据频繁交叉引用。这些就是子域的边界。
  3. 第三步:按子域重构。把交叉的部分抽出来,形成独立的子域服务。这一步需要业务专家参与,别光靠技术团队拍脑袋。
  4. 第四步:持续演进。业务在变,拆分也在变。没有一劳永逸的架构,只有不断调整的架构。

一个小技巧:如果你不确定某个功能该放哪个服务,就问自己一个问题——「这个功能的数据,如果独立出来,会不会让其他服务更难用?」如果答案是「会」,那就先别拆。等数据边界清晰了再动手。

嗯,关于拆分原则,今天就聊到这儿。下一章我们聊聊「服务间的通信方式」,那是另一个容易踩坑的地方。