微服务数量不是目标。用耦合、变更、故障域等 6 个指标,判断该保留、有限拆分还是重组边界。
“服务拆得越细,架构越先进”这句话,在存量系统里往往是误导。你准备再拆一个服务前,先看 6 个指标:拆分必须让一次业务变更涉及更少的人和系统,并把故障影响收在更小的范围内;做不到这两点,新增的通常只是调用、数据同步和排期成本。
服务数不是目标,边界能否独立演进才是。平台化、AI 能力接入会增加编排、检索、鉴权和审计依赖;边界没治理好,先增长的往往是依赖图,而不是研发效率。
能独立部署,不等于能独立演进
Martin Fowler 在《Microservices》中把“围绕业务能力组织”和“可独立部署”列为微服务的典型特征,同时也提醒跨进程调用有成本。把后半句省掉,就容易把“单服务可发布”误当成边界已经成立。
订单规则改动可能只触发一个仓库的流水线,却仍要改库存和促销的契约、补消息消费者的兼容分支、等多个团队的联调窗口。部署动作独立了,业务变更却没有局部化。
更容易漏掉的是,代码里的 import 消失后,耦合并未消失。它变成了 API 版本、超时预算、重试策略、事件语义和表结构演进。评审时应回放一条真实需求的 PR、接口评审、联调单和发布单,而不是只盯依赖拓扑图。
服务边界的质量,体现在一次业务变更能否局部完成,而不是部署清单里有多少个名称。
▲ 拆分只有让变更半径收敛,才会减少协同成本。
我不同意“先拆细,治理以后自然会补上”的做法。治理不是装修项:没有 owner、契约版本策略和异常路径约定,拆出的不是自治能力,而是一串需要共同协调的远程调用。
六个信号,分别指向六类成本
这 6 项不是成熟度打分表。核心交易、受监管流程和内部工具的容忍度不同,同一个现象的权重也不同。它们的用途是让评审团队看到拆分的总成本,并从最近的变更和事故中拿证据。
▎耦合:规则是否仍在跨边界复制
同一类需求反复改同一组服务,先查领域规则是否复制、接口字段是否为兼容不断叠加。若拆成两个服务后每次都要同步改 API 和消费者,耦合只是换了载体。
有状态业务尤其要看“读写分开了,口径却没分开”的情况。订单状态被多个服务各自解释,问题不会出在演示链路,而会在补偿、报表和人工对账时重新汇合。
▎变更:能否独立验收,也能独立回退
不要只数部署频率。抽最近 10 个已上线需求,记录每项涉及的团队、流水线、发布顺序和回退动作。一个服务每天可部署多次,但若每次都要三组人等窗口,频率并不能证明边界独立。
现场常卡在契约兼容期:生产同时存在新旧字段,提供方已完成发布,消费者却没有明确的升级截止日。真正的独立发布,要把兼容窗口、消费者清单和回退责任一并写进变更单。
▎故障域:异常能否止在边界内
多副本解决的是单实例故障,不会自动阻断级联失败。下游超时、消息积压或配置错误发生时,要问用户可见影响止于哪里,以及超时、限流、降级和重试是否在同一预算内协同。
重试策略经常被单独配置,结果是上游超时后重试、下游也重试,积压时反而把恢复窗口压得更窄。Google《Site Reliability Engineering》关于监控的原则很明确:告警应优先指向用户症状,而不是把每个可能原因都变成一条告警。
▎数据:主责、对账和补偿是否闭环
跨服务共写一张表、补偿任务无人验收、重复消费后账实不一致,都说明数据边界尚未成立。幂等不是中间件开关;至少要有业务唯一键、重复处理后的预期结果,以及能核对的对账口径。
有状态能力迁出时,API 切到新库不算完成。历史数据校验、增量同步、失败补偿和审计取证必须由明确责任人验收。双写期间如果没有对账任务和停止条件,接口可以切回,数据通常切不回。
▎团队:谁能端到端拍板并值守
一个服务需要多人审批,却没有端到端 owner;故障发生时 on-call 又找不到主责团队,这种边界只会放大组织摩擦。Conway 定律适合用来检查沟通结构与系统结构是否长期错位,不是按部门组织图硬切服务的理由。
团队边界成立的最低证据,不是仓库归属,而是接口变更、容量申请、事故处置能否落到同一责任链。若一次故障复盘里“谁决定降级”都要跨团队确认,先拆服务没有意义。
▎可观测性:能不能定位到责任边界
不要只问“有没有 APM”。一次请求应能通过 trace ID 串起入口、异步消息和下游调用;告警还要能关联到责任服务与用户症状。只堆组件 CPU、连接池和容器重启告警,值班时仍然无法缩小故障域。
异步链路最容易断在消息头透传和消费端重试。同步链路看似完整,到了队列后只剩业务日志,排查只能靠时间戳拼接;这种情况下继续拆分,只会让定位路径更长。
这 6 个指标是评审信号,不是给架构贴“成熟”或“不成熟”标签的量表。
指标
继续拆分的积极信号
暂停拆分、先治理的信号
评审证据
耦合
高频变更收敛到一个业务边界
同一批服务总是一起改
PR、接口变更记录
变更
可独立验收、发布、回退
多团队排队或锁步发布
流水线、变更单
故障域
异常可限流、降级、隔离
超时或积压沿链路扩散
复盘、压测记录
数据
主责清楚,补偿可验证
共表、口径漂移、对账缺位
血缘、对账记录
团队
一支团队端到端负责
责任与审批分散
值班表、RACI
可观测性
请求可定位到责任边界
只有日志,无链路关联
Trace、告警面板
▲ 服务边界不是接口框,而是一条可验证的责任链。
不必只在“继续拆”和“全量合并”间二选一 ▎保留模块化单体:先把进程内边界守住
数据仍高度一致、耦合主要在代码层、团队和发布窗口有限时,先保留模块化单体更稳妥。用模块依赖规则、领域接口、反腐层和契约测试,先堵住跨模块直连;同一进程内能否守住边界,可通过构建依赖和包可见性验证。
代价是规模扩张后仍可能出现跨模块协同。若连续两三个迭代,典型变更仍长期跨模块且数据主责划不清,再进入有限拆分评估。独立仓库不是边界成立的证据。
▎有限拆分:只抽离变化率或资源曲线不同的能力
某项能力有独立流量、扩容或发布节奏,并且接口消费者、数据主责和 owner 已经说清,才适合有限拆分。先在适配层做只读或旁路校验,再逐步承接写流量;AWS 对 Strangler Fig 模式的公开指引也是通过新旧路径并存来降低替换风险。
切流前要约定回退条件:关键调用时延、错误率或对账差异超过业务可接受范围,就把流量切回旧路径。代价是并存期会增加测试和运维负担;没有时间盒和验收人,“过渡态”会变成永久双写。
▎重组边界:必要时合并总是一起行动的服务
一组服务如果总是共同变更、共同发布、共同值守,合并或重组边界通常比继续细拆更诚实。先收敛契约和数据主责,再把重复编排放入一个明确业务边界;合并后仍要保留模块约束,不能退回职责无限膨胀的大服务。
合并的代价是构建、测试和发布窗口可能变差。若新边界又吞进跨领域职责,或发布窗口明显恶化,就撤回到模块边界重新划分。合并服务也不等于合并所有数据库所有权,schema 和访问边界仍要留下。
演进方案的价值不在目标图多漂亮,而在每一步都有可观测收益、受控并存期和可执行回退。
▲ 演进的关键不是终态,而是每一步都能观察收益并回退。
把下一次评审压缩成 7 个问题
拿最近 10 个有效需求、一次典型事故复盘和当前依赖图,开一场不超过 60 分钟的短评审。答不清的项不是“以后优化”,而是拆分方案还缺前置条件。
1
最近 10 个需求里,哪些服务总是一起变更?
2
这次拆分会取消哪段同步协同,而不是新增哪个调用?
3
新服务的接口、数据主责和 on-call,谁签字负责?
4
下游超时、消息重复或积压时,用户影响止于哪里?
5
新旧路径并存多久,双写、对账和审计由谁验收?
6
用哪个事实证明它比当前更易发布或更易恢复?
7
哪个条件一触发,就必须暂停、切回或合并?
核心交易、订单或审批系统的下一步,到底要不要继续拆?如果你会选择先合并两个总是一起发布的服务,最难跨过的约束是数据一致性、团队边界、发布窗口,还是故障域?
IT架构师联盟
面向企业架构师与技术负责人的专业号:讲企业 IT 架构的选型与演进,把关键决策的取舍和代价讲清楚。
热门跟贴