1. 架构腐化是从什么时候开始的:先认清治理要解决的真实问题
做了这么多年架构设计和系统建设,我发现一个非常普遍的现象:几乎每个系统在立项之初的架构设计文档都是漂亮的,画出来的分层架构、微服务划分、领域模型清清楚楚。可只要跑上一两年,你再打开代码仓库看,会发现当初的设计早就面目全非。这不是某一个团队的问题,而是几乎所有长期演进系统的宿命。
我把这个现象叫作架构腐化,或者叫架构熵增。架构治理这件事,本质上就是在跟这种熵增对抗。
先说几个典型的腐化症状,你看看自己团队有没有中招。第一个是“改不动”:一个看起来很小的需求,开发估完工期说至少要两周,因为你以为改一个服务就行,结果发现业务逻辑散落在五六个服务里,还得同步发版。第二个是“上线靠运气”:每次发版前测试最紧张,因为谁也没法准确说出这次改动影响了哪些下游,只能把相关模块全回归一遍。第三个是“新人恐惧症”:新同事入职三个月,看代码的时间比写代码的时间还多,因为代码里的“历史原因”比注释还多,没人能讲清楚某个模块到底为什么是这样设计的。
这三个症状背后,是同一个根因:架构设计与代码实现之间出现了巨大的漂移,而没有任何机制去发现和纠正这种漂移。架构设计是静态的文档,代码是动态的生命体,如果没有治理机制,代码一定会朝着最省力的方向演化——哪里的耦合已经存在,就在哪里继续堆逻辑;哪个服务已经够大,就在哪里继续膨胀。等到架构腐化到一定程度,大家就开始讨论“重构”,但重构的成本已经高到没人敢动。
所以我要先纠正一个观念:架构治理不是架构设计的附属品,也不是什么高阶的管理话题。它是架构设计能够长期成立的必要条件。你把架构设计看作画图纸,图纸画得再完美,施工过程中没人检查、没人把关、没人纠偏,建出来的楼一定跟图纸是两回事。架构治理就是那个施工监理的角色。
在展开具体怎么做之前,还有一件重要的事情需要说清楚:架构治理不等于流程管控。很多团队一谈到治理,第一反应就是加审批、加评审、加文档,最后把开发同学的节奏拖慢,大家怨声载道,治理变成了纯负担。真正的架构治理应该是轻量、自动、连续的,它的目标是让架构保持在可演进的状态,而不是让所有人围着流程转。这个定位如果不先对齐,后面所有的机制设计都会走偏。
2. 治理抓手的完整清单:原则、机制、度量、工具一个都不能少
把架构治理拆开来看,它其实是四类东西的组合:原则、机制、度量和工具。这四个词听起来都很虚,但它们各自解决的是不同层面的问题,缺一个都不行。我逐一展开讲。
2.1 原则:先定义什么是“不可接受”
做架构治理的第一步,不是去买工具,也不是定流程,而是先回答一个问题:这个系统的哪些状态是我们绝对不能接受的?把这些状态写成显式的规则,就是架构原则。
举个例子,一个微服务架构的系统,最不能接受的状态是什么?我列三条给你感受一下:服务之间出现循环依赖;一个服务同时被超过20个上游调用;领域核心模块反向依赖了基础设施模块。这三条具体不具体?非常具体。但大多数团队的架构原则写的是什么?“保证高内聚低耦合”“遵循分层架构思想”——这种话说了等于没说,因为没法判断对错。
架构原则一定要写成可判定、可执行的形式。什么叫可判定?就是在代码评审的时候,任何人拿原则一对照,就能判断当前代码是否违反。比如“禁止循环依赖”是可判定的,而“保持架构清晰”则没法判定。这一条是整个治理的地基,如果原则本身写得模棱两可,后面所有的度量、工具、评审全都失去了依据。
那原则怎么定?通常的做法是召集核心开发一起梳理。先让每个人列出“最近半年最让你头疼的代码问题”,然后把这些问题归类,抽取出共性的根因,再把根因转成否定句式,就是一条原则。比如很多人都提到“每次改动某个基础模块都会连带挂掉好几个服务”,那对应的原则就是“基础模块禁止反向依赖业务模块,变更基础模块必须经过架构评审”。用团队自己的痛点反推原则,比架构师闭门造车写出来的原则接地气得多,也更容易被认同和执行。
2.2 机制:治理动作如何嵌入日常
原则定了之后,需要有机制来保证原则被执行。机制就是回答“谁来查”“什么时候查”“违反了怎么办”这些问题。
常见的机制包括架构评审、变更委员会、技术债登记、定期架构巡检等。但机制设计有一个非常关键的原则:要嵌入现有的研发流程,而不是另起一套独立流程。如果你让开发在提测、上线、复盘之外再多走一套“架构审批”,那基本没人会配合你,即便配合也是走形式。
我在后面第3节会专门展开讲机制怎么设计,这里先提一个总纲:机制要分层、分场景,让80%的普通变更感受不到治理的存在,只对20%的高风险变更启动约束。这才是治理机制设计的核心心法。
2.3 度量:没有数字就没有管理
度量是架构治理里最容易做歪、但也最有杠杆效应的一环。没有度量的治理,全靠人肉评审来发现问题,效率太低,而且不同评审人的标准还不一致。有了度量,你才能回答“系统当前的架构健康状况如何”“相比上个季度是变好了还是变差了”这两个终极问题。
但度量的坑也特别多。最常见的问题是“度量变成KPI之后,大家开始刷数据”。关于度量指标的选取和阈值设定,我留在第4节专门讲,因为这块值得单独花篇幅。
2.4 工具:把治理动作自动化
最后是工具。工具的作用不是替代人,而是把那些重复、机械、可以自动判断的检查交给机器,让人只关注需要判断力的事情。
依赖关系分析工具、圈复杂度检测工具、API兼容性检查工具、架构守护测试,这些都是架构治理常用的工具手段。特别是架构守护测试的理念很值得推广——把架构原则写成自动化测试代码,跑在CI流水线里,每次提交代码自动检查,违反原则的构建直接失败。这一招能让治理从“偶尔查一次”变成“每次提交都查”,效果是质的飞跃。
工具选型上不需要一上来就上很重的商业平台。很多场景下,开源的依赖分析工具加上你自定义的几个脚本,已经能覆盖80%的检查需求。工具的价值在于连续性,不在于功能数量多。
3. 从评审到看护:治理机制怎么设计才不流于形式
这一节是重点,我讲一下治理机制具体怎么落地。很多团队的问题不是没有机制,而是机制走了形式:评审会开了,但没人认真看;架构委员会成立了,但从不否决任何方案;技术债登记了,但再也没有然后。所以机制设计的核心,是想办法让每个动作都能产生真实反馈。
3.1 分层级评审:让80%的变更畅通无阻,只卡关键节点
我比较推崇的机制是“三分法”的变更分层。
第一层是日常变更。比如普通业务接口的新增、内部实现的调整、非核心模块的小重构,这些变更不影响全局架构,不需要任何额外评审,开发自测通过、代码评审通过就可以正常走发布流程。这层变更如果也卡评审,治理就成了瓶颈,大家很快就会对治理产生抵触情绪。第二层是跨模块变更。比如一个接口的协议变更影响了多个调用方,或者一个新功能涉及三个以上服务的协同修改,这种变更需要模块owner参与评审,重点确认跨模块的接口设计和数据流转是否合理。第三层是架构级变更。比如引入新的中间件、新增一个微服务、核心模块的重大重构、基础设施的技术选型替换,这些变更必须提交架构委员会评审。评审会要讨论的不只是方案本身,还要评估它对现有架构的影响面、对运维体系的冲击、对团队技能的要求。
三层分完之后你会发现,真正需要架构师投入精力的,其实只有第三层。但这一层一定要把好关,因为架构级变更的风险是最大的,也是最难回退的。
3.2 例外机制:治理不是一刀切
再好的原则也会遇到特殊情况。业务催得急、技术方案短期妥协、遗留系统的历史包袱太重,这些时候强行要求合规,只会逼着团队想办法绕开治理。
一个成熟的治理机制必须包含例外通道。我的做法是“例外申请+自动到期”。当团队认为当前变更确实需要临时违反某条架构原则时,可以发起例外申请,说明理由、影响范围、预计恢复时间。例外申请不是审批通过就完了,它会自动记录到技术债清单里,并且设置到期时间。到期之前团队必须给出处理方案——彻底解决、或者申请延期。这样既给了业务灵活性,又让每一个例外都暴露在阳光下,不会变成永久性债务。
这个机制推行时最需要注意的是:例外申请的审批不能太松,否则所有人都会走例外通道,原则就形同虚设了。我一般要求例外必须由架构师和模块Owner双方确认,并且一个团队同时存在的活跃例外不超过五个。如果超过这个数,说明原则本身可能有问题,需要重新审视而不是继续开例外。
3.3 巡检节奏:按周、按月、按季度分别看什么
治理动作要有节奏感,不能想起来才查一下。我常用的节奏是这样安排的:每周做一次自动化检查结果回顾,看本周有没有新增的架构违规,如果有,立即定位是在哪个变更引入的,尽快处理。这个动作最好由工具自动产出报告,人工只需要扫一眼。
每月做一次人工巡检,关注工具查不出来的问题,比如模块职责是否开始模糊、接口粒度是否合理、团队对架构的理解是否出现偏差。这种巡检不需要很正式,约上几个核心开发,花半天时间过一遍最近的架构相关变更,聊一聊感受就行。每个季度做一次正式的健康度评估,基于度量指标和季度内的治理记录,输出一份架构健康度报告,汇报给技术管理层。这份报告要有结论——系统当前处于什么状态、哪些问题必须在下个季度解决、需要什么资源支持。
季度报告的目的不只是向上汇报,更是为了让技术团队自己有清晰的方向感。我见过不少团队,平时不觉得架构有问题,一到季度报告时候才发现积累了十几个架构债,这才意识到治理的价值。
3.4 评审会的形式感:避免变成“过场会”
架构评审会是最容易形式化的场景。我的经验是,评审会绝对不能变成方案宣讲会。方案宣讲会是什么样的?开发者做了一堆PPT,评委们边听边点头,最后说一句“整体不错,注意一下XX细节”就结束了。这种会开一百次也不会产生治理价值。
有效的架构评审会应该提前把材料发给评委,让评委在会前花时间看并给出初步意见。开会的时候,不再花时间讲背景和整体设计,只讨论分歧点和风险点,大家直接开炮。如果一场评审会超过一小时,那说明会前准备不到位,要么是材料写得不够清楚,要么是评委没有提前看。评审会结束必须有明确的结论:通过、有条件通过、打回重做,三种结论不能模糊。有条件通过的一定要列出具体条件是什么、由谁跟进、什么时候复查,不能含糊带过。
这些细节看起来是流程问题,其实决定了治理是否有效。一场不痛不痒的评审会,比不开还糟糕,因为它消耗了所有人的时间,还给大家留下“架构评审就是走流程”的负面印象。要扭转这个印象,只需要做到一条:认真开好每一次评审会,让每个参会的人都觉得这个会值得花时间。
4. 量化不等于僵化:架构治理指标怎么定才有用
指标是治理的眼睛。但指标也是双刃剑——用好了能驱动改进,用歪了会带来一系列反噬。这一节我把指标设计的思路和一些常见坑都说透。
4.1 核心指标集:从依赖、复杂度、一致性三个维度入手
不要追求大而全的指标体系和华丽的度量看板。我觉得指标只要能覆盖三个维度就够了:依赖健康度、模块清晰度、变更一致性。
依赖健康度常用的是这几种指标:循环依赖个数,这个是硬指标,正常应该为零;反向依赖数量,即基础模块被哪些上层模块依赖、以及基础模块是否反向依赖了上层模块;平均扇入扇出,单个服务的调用方数量和依赖方数量,过高就要警惕。这些指标用来回答一个问题:系统的依赖关系是否还处于可控状态。
模块清晰度衡量的是代码实现跟架构设计的偏离程度。最常见的手段是“架构分层合规率”,按架构设计文档中定义的分层规则和模块边界,扫描实际代码的包结构、依赖方向,算出有多少代码违反了设计边界。这个指标最有价值的地方在于,它能直接定位到具体的包和类,让治理动作能落到具体代码上,而不是停留在“全局比较健康”这种模糊判断。
变更一致性关注的是:架构被破坏的频率、例外申请的数量和存续时长、核心模块的变更频率和变更集中度。如果一个核心领域模块每周被十几个非核心需求反复改动,那很大概率说明模块边界划分出了问题,或者模块的扩展方式不够合理,需要介入而不是继续放任。
4.2 Goodhart陷阱:指标变成目标,就会失去意义
指标设计最大的坑,就是Goodhart定律说的事情:当一个指标成为目标,它就不再是个好指标了。
我见过一个很典型的例子。某团队为了控制服务数量,定了一个指标“单服务最大接口数不超过20个”。结果怎么样?开发确实不再往一个服务里加接口了,他们学会了把接口改个名字塞进另一个服务,或者在网关层做转发,直接绕过了统计。指标好看了,架构却更乱了。
所以我在设计指标的时候,有一条基本原则:凡是能被人为“优化”但实际没有改善架构的指标,都要警惕。反制的方法是组合使用指标,不让单一指标承担过大的压力。比如“接口数”要和“服务的平均依赖数”“跨服务调用占比”一起看,防止通过拆分服务来刷单一指标。另外,指标数据最好由工具自动采集,不要依赖人工填写,人工填写必然有水分。
还有一个很重要的心法:指标的作用是定位问题,而不是考核团队。如果你把架构指标纳入绩效考核,团队的理性选择就是美化数字而不是真正改进。我见过最好的用法是,月度架构健康报告出来后,大家关注的是“这个季度环比改善了还是恶化了”“恶化出现在哪里”,而不是“谁的数字最差”。指标是手电筒,不是鞭子。
4.3 阈值设定的方法论:从历史数据反推,而不是拍脑袋
阈值怎么定?很多团队拍脑袋定一个“圈复杂度不能超过10”,结果发现大量存量代码都在15以上,新代码倒是符合了,但架构没有变好。正确的做法是先测量、再定标。
拿到一个系统之后,先让工具跑一遍全量扫描,把当前所有相关指标的基础数据拉出来,算出分位数。比如依赖数量,看看现在的服务里最大的扇入是多少、最小的是多少、中位数是多少,然后以“中位数附近的20%不能超过、当前最差的一批在未来两个季度逐步收敛”这种思路来定阈值。也就是说,阈值是动态演进的——第一季度的目标可以是“不再新增超过当前最差水平的依赖”,第二季度可以是“最差的20%全部降低30%”,第三季度再往更严格的方向收敛。
这种渐进式的指标定法,比一刀切要现实得多,也更容易得到开发团队的配合。毕竟没有人愿意突然被要求把自己维护了三年的模块在一周内整改到完全合规,这根本不现实。但如果你说的是“我们先用三个月停止恶化,再用一个季度完成一轮集中的债务削减”,大家的接受度会高很多。
4.4 度量的最终出口:一定要连接到决策
指标最后必须连接到决策,否则就是纯展示。什么叫连接到决策?就是有了这个指标,你会做出一个跟之前不一样的判断或动作。
举个例子,如果你发现某个服务的循环依赖数量在一个月内从2涨到了8,那你的决策就是:立即召集相关模块的owner开一次对齐会,找出引入循环依赖的那几次变更,逐个解决。再比如,季度报告显示“核心领域模块的被依赖度持续升高”,那你的决策就是:拒绝在这个模块里继续加新功能,要求需求方走新的拆分方案。指标只有能驱动这样的具体动作,它才算是治理体系的有机组成部分,否则就只是墙上的一张美化图表。我见过太多团队做了很漂亮的架构看板,但大家只是偶尔看一眼,然后什么都不发生,这种度量就是纯成本。
5. 架构治理真正的难题:协同、权力和激励
很多做架构治理的人,容易把注意力全放在工具和指标上,觉得有一套自动化的守护系统就万事大吉了。但真正做过一段时间的人会告诉你,最难的从来不是技术问题,而是协同问题。
5.1 架构师没有“命令权”,怎么推进治理落地
先说一个现实:在很多公司里,架构师这个角色有责无权。你要对架构的健康度负责,但你并没有直接指挥开发团队的权力,也不掌握团队的绩效和晋升。这种情况下推行治理,如果全靠“说服”和“人情”,一定走不远。
我的经验是,治理要获得实际推动力,必须绑定一些不可绕过的节点。最有效的是发布环节。如果架构守护检查是发布流水线的一环,代码不通过就发不上去,那么不需要任何人去“说服”开发,他们也会主动修复架构问题。这就是把技术手段当作治理权的一种变通。另一个有效的节点是项目立项和技术选型。任何新项目、新系统或重大的技术改造,必须过架构评审,否则不予批准资源。这两条卡住之后,架构师在关键节点上就有了实际的控制力,而不只是靠一张嘴推动。
当然这里要小心,不能把治理变成“卡人”的工具。架构师的价值是帮团队把事情做成,而不是增加阻力。所以我推动治理的时候,总会强调一个导向:架构守护是在帮大家“提前拦下未来要还的债”,而不是在挑毛病。带治理视角的评审会,讨论的问题是怎么设计才能让后续的开发更轻松、发布更安全、维护更简单,而不是纯从理论上评判对错。
5.2 让业务方也从治理中受益
架构治理如果只让技术团队受益,业务方是没有动力配合的。但如果你能证明治理和业务目标直接相关,局面就会完全不一样。举个例子,某次业务提了一个快速上线的新需求,但方案需要绕过正常的服务边界。如果架构师只说“这不符合架构原则”,业务方会觉得很抽象。但如果你换一个说法:“这个改法会让下单接口多一次跨服务调用,链路响应时间预计增加80毫秒,并且后续每次改促销逻辑,都得同时改两个服务同步发版,线上出问题的概率会明显上升。”业务方立刻能听懂,而且大概率会主动配合你调整方案。
把架构问题翻译成业务语言,是架构师推动治理的一项关键能力。响应时间、故障率、上线效率、维护成本,这些才是业务方真正关心的东西。每一次治理动作,你都应该尝试用业务可感知的语言来描述收益。时间长了,业务方会逐渐形成一种心智:架构治理不是在给他们添麻烦,而是在保护业务的稳定性和交付效率。
5.3 奖励比惩罚更有效:正反馈循环怎么建
治理的持续推进需要正反馈。如果团队做了半年的架构改进,业务没有任何感知,开发自己也感觉不到明显变化,那这个治理运动迟早会熄火。所以要设计一些能快速见效的早期目标,让大家尝到甜头。
我常用的做法是:第一个季度不追求大而全的治理,而是选一个痛点最集中的模块做专项整治。比如一个典型的场景是订单服务的调用方太多,每次改动都要协调五六个团队联调。一个季度集中做一轮接口收敛和服务拆分,把调用方从20个降到了8个。这个改进做完之后,最直接的收益是:订单模块的联调沟通成本明显下降,发布次数可以更频繁,测试回归的范围也小了。开发同学自己会感觉到“现在改东西明显轻快多了”,这种感受比任何KPI都有说服力。
治理推进者还要注意及时广播战绩。每次专项整治完成,写一篇简要的复盘发到团队群,说清楚改了什么、带来了什么收益、过程中踩了什么坑。这既是知识沉淀,也是给参与同学的公开认可,能形成一个正向的循环。治理不是一次性的运动,它需要持续的小胜利来维持士气。
6. 从现状出发的落地路线:新系统与存量系统的治理策略完全不同
很多人问架构治理应该从什么时候开始做,我的回答是:新系统从第一天就做,存量系统从盘点开始做。这两种场景的治理策略完全不同,我分开说。
6.1 新系统:在第一天就植入治理基因
新项目的优势是还没有历史包袱,原则和工具的落地成本最低。但新项目也有劣势,就是团队会觉得“系统刚搭起来,哪有什么架构问题”,治理很容易被搁置到“以后再说”。
我的建议是,新项目在启动阶段就做三件事。第一,把架构原则写进项目交接文档,并且让工具扫描从第一个提交就开始跑起来,哪怕当前代码量很小,也要把规则建立起来。第二,明确架构评审的分层标准,项目初期就定义清楚哪些变更算架构级变更,哪些是日常变更,确保第一个微服务的拆分、第一个中间件的引入都走评审流程。第三,选定架构治理工具链,把依赖分析、复杂度检查、架构守护测试全部配置在CI流水线里。工具从第一天就接入,后面就没有任何“历史债”需要清理。
新项目治理的最大价值是“未病先治”,成本最低、效果最好。很多团队嫌麻烦,觉得项目刚开始没必要搞这些,结果往往是系统上线半年后,架构已经开始混乱,才想起来要做治理,这时候再返工,成本比一开始就做高好几倍。
6.2 存量系统:先做架构盘点,再启动治理
存量系统的治理,最忌讳的是直接上全套指标和工具,然后宣布“从今天起我们要严格执行架构规范”。这种做法的后果是:工具扫出一堆历史违规,团队一看要改的代码量太大,直接摆烂,治理运动还没开始就结束了。
正确的姿势是先做架构盘点和基线固化。用工具对系统做一次全量扫描,输出当前的依赖关系图、模块边界、复杂度分布、关键代码路径。不要指望一次盘点就把所有问题都弄清楚,重点是先建立“当前系统的真实状态”这个基线。盘点的过程,其实也是团队重新理解自己系统的过程,很多人做完盘点才发现,原来系统里已经藏了这么多自己都不知道的依赖关系。
然后做债务分级。把盘点出来的问题分为三类:影响线上稳定性的,必须立即处理;影响迭代效率的,安排在一个季度内集中处理;纯粹的规范性问题,作为长期优化逐步推进。一定要优先处理影响线上稳定性的问题,因为这类问题最容易获得业务方的支持。用一次线上故障的真实案例来推动治理,比开十次治理宣贯会都管用。
6.3 前三个月的推进节奏:从轻到重、小步快跑
第一到第四周,完成工具接入和架构盘点,输出基线报告,选定一个痛点模块做试点。这个阶段的目标不是做得多,而是搭好机制。第五周到第八周,试点模块的专项整治开始,同时日常的自动化检查全面运行,每周回顾一次违规报告。这个阶段的重要节点是试点模块的改进初见成效,让大家感受到治理确实有用。第九周到第十二周,把试点经验固化到流程里,更新架构原则和评审标准,然后向全系统推广。这个阶段要特别注意,推广的力度要“由轻到重”,先从最容易接受的新模块开始,再逐步覆盖到核心老模块。
前三个月最容易犯的错是用力过猛。我曾经见过一个团队,第一周就要求所有模块圈复杂度必须降到10以下,结果光梳理存量代码就花了两个星期,什么治理动作都没做,最后全盘搁浅。我现在特别信奉一个原则:治理的节奏要慢到让团队消化得动,快到来不及产生新的坏味道。这中间的火候,只能靠一线的实际情况来把握。
7. 关于架构治理,我最后想分享的几点真实体会
架构治理这件事,做的时间越长,越觉得它像一门“平衡的艺术”。它不是简单地把规则定下来、把工具跑起来就完事,而是要持续在各种力量的拉扯中找平衡。
一是要在约束和效率之间找平衡。规则太多太细,会拖垮研发节奏,最后大家把所有规则都当成形式,整体约束力反而下降。规则太少太粗,又起不到防护作用。所以原则定完之后,要定期回访团队,问一句“这些规则有没有哪条是你们觉得没意义的”。如果某条规则连续三个月没有拦截到任何问题,可能它不是保护了架构,而是已经被人悄悄绕过了,需要重新评估。
二是要在自动化守护和人工判断之间找平衡。工具能查循环依赖,但查不出模块职责的模糊;能统计接口数量,但判断不了接口粒度合不合理。架构治理配比合理的话,自动化工具能解决70%的问题,剩下30%必须靠架构师的经验和判断力。不要试图把所有事情都自动化,那是自欺欺人。
三是要在“当下”和“未来”之间找平衡。治理不能只盯着当下系统的健康度,也要关注系统未来能否持续演进。一个当前看起来很健康、但核心模块已经庞大到无法扩展的系统,比一个当前有一些技术债、但核心模块边界清晰、易于拆分的系统更危险。看治理效果,要放在六到十二个月的时间跨度上来评价,不能只看当下的数字。
如果你正要开始推动架构治理,我的建议是从一个小切口开始,先选一个你最担心的模块,把工具跑起来,把自动化检查建起来,把一个专项整治做起来。不要试图在第一周就建完所有的体系,治理是慢功夫,但它一旦跑起来,会像一个自动运转的健康卫士,持续守护住架构设计的初衷。