架构评审会上画出来的图是三个清晰的域,代码仓库里却是五个团队交叉提交同一批模块。图上那条边界线,在组织里根本没有对应的沟通路径——不是图画错了,是图画在了组织没有能力维护的位置上。
康威定律常被当成一句俏皮话引用,真正可操作的部分只有一句:系统的形状会收敛到组织的沟通形状。它不是宿命,是机制。机制意味着可以反着用,但只能通过改组织,不能通过改图。
1. 三种边界别混为一谈
| 边界类型 | 落在哪 | 谁维护 | 破了会怎样 |
|---|---|---|---|
| 逻辑边界 | 包结构、模块、依赖方向 | 架构师 | 编译期耦合,可重构 |
| 部署边界 | 进程、服务、仓库 | 发布流程 | 一次发布牵连多个团队 |
| 组织边界 | 汇报线、值班表、评审权限 | 管理者 | 无人对失败负责,变更排队 |
判据只有一条:三种边界大致对齐时,边界才是真的。只在图上成立的那一种,叫设计意图。
# CODEOWNERS —— 把组织边界写成可执行的默认评审人
/service/order/ @team-order
/service/pricing/ @team-pricing
/shared/model/ @team-platform @team-order @team-pricing
最后一行是信号:一个路径需要三个团队共同 owner,说明它是共享内核,也是将来跨团队变更的热点。
2. 康威定律的正确读法
它说的不是"系统一定长得像组织",而是:接口的形状由沟通成本最低的那条路径决定。
| 常见误读 | 实际机制 | 后果 |
|---|---|---|
| 组织定了,系统只能这样 | 沟通路径可以被显式设计 | 放弃设计权,等系统自然长歪 |
| 图画好就能逆康威 | 逆康威只能改组织,不能改图 | 图改了协作没改,落地成伪自治 |
| 团队越大沟通越充分 | 沟通成本随人数近似平方增长 | 大团队边界反而更糊 |
逆康威的可操作顺序是固定的一句:先改汇报与值班,再改发布流水线,最后改代码边界。反过来做,等于让代码去承担组织的债。
3. 四种拓扑与适用条件
| 类型 | 负责什么 | 适用条件 | 不适用 |
|---|---|---|---|
| 业务流团队 | 一条端到端业务能力 | 业务能切成相对独立的用户旅程 | 业务耦合在同一个事务里 |
| 平台团队 | 内部自助能力(构建、部署、观测) | 三个以上团队重复造同一件东西 | 需求只来自一个团队 |
| 复杂子系统团队 | 高专业度组件(计费、风控模型) | 认知负荷高且需长期专人 | 组件简单,只是懒得学 |
| 赋能团队 | 把某项能力教会业务团队 | 有扩散路径与退出条件 | 变成长期外包,永不退出 |
赋能团队最容易腐化:它的成功标志是被赋能团队不再需要它。
赋能团队的健康指标(按季度看趋势)
- 被赋能团队独立完成该能力变更的比例:↑
- 由赋能团队代提交的 PR 数:↓
- 赋能团队人数:不变或↓
4. 团队边界的四个判据
| 判据 | 观测方式 | 及格线(典型量级,按团队实际核对) |
|---|---|---|
| 认知负荷 | 组件数、每人负责的服务数 | 能完整说清自己拥有的 3–5 个服务 |
| 发布节奏 | 独立发布的频率 | 不等别人就能发版 |
| 沟通成本 | 每周跨团队会议时长 | 变更不需固定例会才能推进 |
| 所有权 | 谁能改、谁能批 | 出故障只有一个团队接电话 |
四条必须同时成立。只满足所有权、不满足发布节奏,就是"责任在你、权限不在你"。
5. 认知负荷是硬约束,不是人数
团队规模的上限不取决于人数,取决于这个团队要理解多少不同的东西。
认知负荷粗算(用于团队之间比较,不用于绝对判定)
load = 拥有的服务数 × 1
+ 独有技术栈数 × 2
+ 依赖的外部团队数 × 1.5
+ 需理解的领域概念数 × 1
经验区间:> 15 时团队开始出现"只改自己那块"的行为
人数可以加,负荷不能靠加人摊薄——新人进来先增加沟通成本。判断顺序永远是:先减掉不必拥有的东西,再谈加人。
6. 边界错位的两个后果
| 后果 | 表现 | 根因 |
|---|---|---|
| 跨团队变更 | 一个需求要开三个 PR、找两次评审 | 服务边界切在组织边界之外 |
| 伪自治 | 能独立部署,但每次都要同步发 | 共享数据库或共享契约仍在 |
伪自治的识别方法很土但有效:能否在一个团队的值班范围内独立回滚。回滚要拉上别人,就不是自治。
# 跨团队变更的候选热点:按路径聚合提交者
git log --since="90 days ago" --name-only --pretty=format:'A:%an' \
| awk '/^A:/{a=substr($0,3); next} NF{print a"\t"$0}' \
| sort | uniq -c | sort -rn | head -30
同一路径出现多个作者团队,就是该查的地方。
7. 平台团队为什么会变成审批部门
| 阶段 | 平台的行为 | 团队的感受 | 转折信号 |
|---|---|---|---|
| 起步 | 提供模板与文档 | 省事 | 无 |
| 扩张 | 开始收口"统一规范" | 需要申请 | 变更要提单 |
| 审批化 | 变成唯一合法路径 | 绕开它偷偷自建 | 出现影子流水线 |
平台的价值在自助,不在统一。判据是它交付的是"能力"还是"决定":交付决定的那一刻,它已经不是平台团队了。
平台请求三分类(防审批化的最小机制)
1. 自助项:文档 + 模板即可完成,不进工单
2. 配置项:改参数、开配额,控制台自助并留审计
3. 例外项:真实一次性需求,必须回流成 1 或 2
三成以上请求落在第 3 类 = 平台缺能力,不是缺流程
8. 内部开源与代码所有权
| 模式 | 谁能改 | 成本 | 失效形态 |
|---|---|---|---|
| 强所有权 | 只有 owner 团队 | 沟通成本高,质量稳 | owner 成瓶颈 |
| 内部开源 | 任何人提 PR,owner 评审 | 评审负担 | 评审排队,PR 腐烂 |
| 无所有权 | 任何人可直接合 | 短期快 | 无人理解全局,回归频发 |
内部开源能成立的前提是评审 SLA 与测试覆盖。缺这两条,它只是把瓶颈从"没人能改"换成"没人敢合"。
9. 分布式单体的组织根源
共享数据库、共享发布窗口、共享契约仓库,只要还有一样,服务拆得再细也是分布式单体。
判断是不是分布式单体(命中两条以上即为是)
[ ] 多个服务连同一个库、同一个 schema
[ ] 发布必须按固定顺序或同一时间窗
[ ] 一个服务的字段变更要另一个团队改代码
[ ] 联调环境只有一个,排队使用
[ ] 故障演练必须全员到场
10. 先动组织还是先动系统
| 现状 | 先动什么 | 理由 |
|---|---|---|
| 图与组织完全错位 | 组织 | 图无法在无协作路径处存活 |
| 组织已就位、代码还糊着 | 代码(绞杀者式) | 组织不必再折腾 |
| 两者都乱 | 先切一个最小闭环 | 用可度量的切片验证 |
| 业务正在剧变 | 都别动 | 稳定后再切,否则切完又要切 |
11. 团队规模与服务数量的匹配
| 团队人数 | 能稳定拥有的服务数(典型量级) | 建议 |
|---|---|---|
| 3–5 | 2–3 | 一个业务流 + 一个共享组件 |
| 6–9 | 3–5 | 上限,超过就开始互相等 |
| 10+ | 先看认知负荷 | 加人 ≠ 加服务 |
服务数超过团队能同时理解的上限,运维负担会以指数方式体现:值班表、升级路径、依赖图一起失控。
12. 演化,而不是重组
一次拓扑调整的最小步骤(不要一次全动)
1. 选一个切片:端到端、有真实用户、可度量
2. 明确所有权:代码、值班、发布权限一起给
3. 迁移依赖:先切读路径,再切写路径
4. 观察两个发布周期:跨团队依赖数是否下降
5. 成立下一个切片,重复
6. 旧边界保留一个季度再删除,留退路
13. 度量:三个就够
| 指标 | 采样方式 | 期望方向 |
|---|---|---|
| 跨团队依赖数 | CODEOWNERS + 提交路径聚合 | 下降 |
| 变更前置时间 | 首个提交到生产的中位数 | 下降 |
| 认知负荷主观评分 | 每季度一次 1–5 分自评 | 稳定在 3 以下 |
# 变更前置时间粗测:合并提交到主干的时间差
git log --merges --since="60 days ago" --pretty=format:'%h %ct %s' | head -50
数字只用于看趋势,不用于排名团队。排名一出现,数据就会开始说谎。
14. 排错
| 现象 | 原因 | 处理 |
|---|---|---|
| 拆完服务发布反而更慢 | 共享契约或共享库没拆 | 先拆数据与契约,再谈部署 |
| 每个需求都要开三方会 | 边界切在协作路径之外 | 移动边界或移动人,二选一 |
| 平台团队天天救火 | 平台缺能力,被迫人工兜底 | 把兜底项回流成自助能力 |
| 团队说自己"什么都得管" | 认知负荷超限 | 移交一个组件,或并入相邻团队 |
| 重组三个月后又乱 | 一次动了太多切片 | 缩小切片,按季度推进 |
15. 边界
| 场景 | 拓扑设计的价值 | 该做什么 |
|---|---|---|
| 团队小于 10 人 | 很低 | 按人分工,别引入拓扑名词 |
| 单一产品、单一边界 | 低 | 一个团队端到端负责 |
| 业务尚未稳定 | 负值 | 先稳定需求,重组会被浪费 |
| 多产品、多地域 | 高 | 按业务流切,平台能力先行 |
拓扑设计是给已经出现的摩擦做归因,不是给还没出现的摩擦做预防。没有摩擦时做拓扑,通常只是给组织加了一层词汇。
16. 自测
- 你的架构图上有几条边界,能在 CODEOWNERS 里找到对应行?
- 逆康威应该按什么顺序动,先改图会怎样?
- 赋能团队的退出条件写在哪,谁来判断它达成了?
- 同时满足所有权却不满足发布节奏,问题出在哪一层边界?
- "是不是分布式单体"那五条,你的系统命中几条?
- 认知负荷超限时,第一反应该加人还是减组件,为什么?