跳到主要内容

微服务拆分的收益与账单

微服务拆分用独立部署换取变化、扩缩容和故障边界,同时把进程内问题转化为分布式系统问题。

1. 先写出拆分目标

“系统太大”很难直接指导拆分。开始之前需要选定可以验证的目标,例如:

  • 订单模块每周发布,其他模块只能每月发布,希望降低发布协调;
  • 搜索流量波动明显,希望独立扩缩容;
  • 支付故障曾拖垮整个应用,希望建立资源和故障隔离;
  • 一个跨地域团队需要独立维护完整业务能力;
  • 某类数据有单独的合规和访问控制要求。

目标要有基线指标,包括发布频率、变更前置时间、故障影响范围、资源使用和团队等待时间。没有基线,拆分完成后也无法判断收益。

2. 服务围绕业务能力划分

按 Controller、Service、DAO 等技术层拆分,会让每个请求都跨多个服务。按数据库表拆分,则会把原本需要同一事务维护的规则切开。

更稳定的候选边界来自业务能力和限界上下文。一个服务应拥有:

  • 清楚的业务责任与接口;
  • 自己的状态和写入规则;
  • 可独立测试、发布和回滚的代码;
  • 明确的维护团队和运行责任。

限界上下文不要求与服务一一对应。一个上下文可以先由一个服务实现,也可以在规模扩大后由几个内聚服务共同实现。拆分粒度要通过真实变化和调用数据校准。

3. 独立部署是主要收益

服务可以独立部署后,团队能够在不协调整套系统发布的情况下交付变化。这个收益成立需要接口向后兼容、自动化测试、独立流水线和清楚的所有权。

其他常见收益包括:

  • 热点服务单独扩容,不必复制整个应用;
  • 故障和资源耗尽可以限制在一个边界内;
  • 不同能力可以选择合适的存储和运行时;
  • 团队围绕端到端业务结果负责。

如果每次需求仍要同时修改和发布五个服务,独立部署只是名义能力。此时应该先处理服务边界和契约,而不是继续增加服务数量。

4. 网络调用带来失败语义

进程内方法调用通常只有成功或抛出异常;远程调用还会遇到超时、连接中断、部分成功、重复请求和响应丢失。

服务拆分后需要补齐:

  • 超时预算、取消传播和有界重试;
  • 幂等键、去重与补偿;
  • 限流、熔断、隔舱和降级;
  • 服务发现、证书与身份认证;
  • 跨服务日志、指标和 trace。

这些能力需要开发、测试和持续运维,不能只计算新增的服务器成本。

5. 数据所有权增加一致性成本

独立服务应拥有自己的写入模型。原来的本地事务被切开后,业务流程可能需要事件、outbox、Saga、对账和人工修复。

共享数据库可以作为迁移阶段,但要先划清表的写入权。多个服务长期直接修改同一批表,会导致版本无法独立、规则被绕过,并把故障重新耦合在数据库中。

对跨服务查询,可以选择 API 聚合、读取投影、搜索索引或数据仓库。不要为了恢复一次 SQL join,就让服务共享全部内部表结构。

6. 服务数量形成固定账单

每个服务至少需要构建、部署、配置、监控、告警、安全更新、容量和应急责任。服务数量增加后,还会出现:

  • 本地开发和端到端测试环境更复杂;
  • API 与事件版本需要长期兼容;
  • 值班人员面对更大的依赖图;
  • 空闲副本和平台控制面消耗资源;
  • 跨团队排障和变更协调增加。

团队如果还没有自动化交付、集中观测、服务目录和明确 on-call,拆分速度通常会超过治理能力。

7. 识别拆分过细

这些信号说明服务边界可能过细:

  • 大部分请求都要同步经过多层服务;
  • 多个服务必须同时发布;
  • 一个小团队维护几十个低流量服务;
  • 大量业务事务都需要 Saga;
  • 服务只有一张表和一组机械 CRUD;
  • 故障与扩缩容从未真正独立。

合并服务不代表架构退步。边界目标是降低整体变化成本;两个服务长期共同变化时,把它们放回同一部署单元可能更合理。

8. 渐进式拆分

可控的拆分通常按以下顺序推进:

  1. 在单体内部建立业务模块和数据所有权;
  2. 记录调用、变更和负载,选择收益最明确的候选模块;
  3. 先定义稳定契约和兼容策略;
  4. 迁移一条可独立验证的业务路径;
  5. 灰度流量,比较原有基线;
  6. 达到退出条件后删除旧路径。

每次只解决一项主要目标。性能、组织、技术栈和全面重写同时推进,会让问题归因和回退都变得困难。

9. 面试题

9.1 微服务应该怎样拆,拆得太细会有什么问题

出现公司:阿里巴巴、字节跳动、美团

考察重点

  • 拆分目标和业务边界。
  • 独立部署、扩缩容与故障隔离的收益。
  • 网络、数据、测试、运维和组织成本。

相关内容:第 1 节“先写出拆分目标”至第 8 节“渐进式拆分”。

参考回答

我会先明确拆分要解决的具体问题,并记录发布频率、故障范围、负载和协作时间等基线。候选边界按业务能力、共同变化、不变量和团队责任识别,服务要拥有自己的接口、状态和发布流程,不能按技术层或数据库表机械拆分。

拆分的收益是独立部署、扩缩容和故障隔离;账单包括远程调用失败、分布式一致性、契约兼容、观测、安全、测试和 on-call。拆得太细会出现长同步链、频繁联动发布、Saga 过多和团队维护负担。实践中先治理单体模块,再选择收益最明确的一条路径渐进迁移,并用原有指标验证收益。