治理:對抗架構(gòu)腐化與熵增的工程實踐)
1. 架構(gòu)腐化是從什么時候開始的先認清治理要解決的真實問題做了這么多年架構(gòu)設(shè)計和系統(tǒng)建設(shè)我發(fā)現(xiàn)一個非常普遍的現(xiàn)象幾乎每個系統(tǒng)在立項之初的架構(gòu)設(shè)計文檔都是漂亮的畫出來的分層架構(gòu)、微服務(wù)劃分、領(lǐng)域模型清清楚楚。可只要跑上一兩年你再打開代碼倉庫看會發(fā)現(xiàn)當初的設(shè)計早就面目全非。這不是某一個團隊的問題而是幾乎所有長期演進系統(tǒng)的宿命。我把這個現(xiàn)象叫作架構(gòu)腐化或者叫架構(gòu)熵增。架構(gòu)治理這件事本質(zhì)上就是在跟這種熵增對抗。先說幾個典型的腐化癥狀你看看自己團隊有沒有中招。第一個是“改不動”一個看起來很小的需求開發(fā)估完工期說至少要兩周因為你以為改一個服務(wù)就行結(jié)果發(fā)現(xiàn)業(yè)務(wù)邏輯散落在五六個服務(wù)里還得同步發(fā)版。第二個是“上線靠運氣”每次發(fā)版前測試最緊張因為誰也沒法準確說出這次改動影響了哪些下游只能把相關(guān)模塊全回歸一遍。第三個是“新人恐懼癥”新同事入職三個月看代碼的時間比寫代碼的時間還多因為代碼里的“歷史原因”比注釋還多沒人能講清楚某個模塊到底為什么是這樣設(shè)計的。這三個癥狀背后是同一個根因架構(gòu)設(shè)計與代碼實現(xiàn)之間出現(xiàn)了巨大的漂移而沒有任何機制去發(fā)現(xiàn)和糾正這種漂移。架構(gòu)設(shè)計是靜態(tài)的文檔代碼是動態(tài)的生命體如果沒有治理機制代碼一定會朝著最省力的方向演化——哪里的耦合已經(jīng)存在就在哪里繼續(xù)堆邏輯哪個服務(wù)已經(jīng)夠大就在哪里繼續(xù)膨脹。等到架構(gòu)腐化到一定程度大家就開始討論“重構(gòu)”但重構(gòu)的成本已經(jīng)高到?jīng)]人敢動。所以我要先糾正一個觀念架構(gòu)治理不是架構(gòu)設(shè)計的附屬品也不是什么高階的管理話題。它是架構(gòu)設(shè)計能夠長期成立的必要條件。你把架構(gòu)設(shè)計看作畫圖紙圖紙畫得再完美施工過程中沒人檢查、沒人把關(guān)、沒人糾偏建出來的樓一定跟圖紙是兩回事。架構(gòu)治理就是那個施工監(jiān)理的角色。在展開具體怎么做之前還有一件重要的事情需要說清楚架構(gòu)治理不等于流程管控。很多團隊一談到治理第一反應(yīng)就是加審批、加評審、加文檔最后把開發(fā)同學的節(jié)奏拖慢大家怨聲載道治理變成了純負擔。真正的架構(gòu)治理應(yīng)該是輕量、自動、連續(xù)的它的目標是讓架構(gòu)保持在可演進的狀態(tài)而不是讓所有人圍著流程轉(zhuǎn)。這個定位如果不先對齊后面所有的機制設(shè)計都會走偏。2. 治理抓手的完整清單原則、機制、度量、工具一個都不能少把架構(gòu)治理拆開來看它其實是四類東西的組合原則、機制、度量和工具。這四個詞聽起來都很虛但它們各自解決的是不同層面的問題缺一個都不行。我逐一展開講。2.1 原則先定義什么是“不可接受”做架構(gòu)治理的第一步不是去買工具也不是定流程而是先回答一個問題這個系統(tǒng)的哪些狀態(tài)是我們絕對不能接受的把這些狀態(tài)寫成顯式的規(guī)則就是架構(gòu)原則。舉個例子一個微服務(wù)架構(gòu)的系統(tǒng)最不能接受的狀態(tài)是什么我列三條給你感受一下服務(wù)之間出現(xiàn)循環(huán)依賴一個服務(wù)同時被超過20個上游調(diào)用領(lǐng)域核心模塊反向依賴了基礎(chǔ)設(shè)施模塊。這三條具體不具體非常具體。但大多數(shù)團隊的架構(gòu)原則寫的是什么“保證高內(nèi)聚低耦合”“遵循分層架構(gòu)思想”——這種話說了等于沒說因為沒法判斷對錯。架構(gòu)原則一定要寫成可判定、可執(zhí)行的形式。什么叫可判定就是在代碼評審的時候任何人拿原則一對照就能判斷當前代碼是否違反。比如“禁止循環(huán)依賴”是可判定的而“保持架構(gòu)清晰”則沒法判定。這一條是整個治理的地基如果原則本身寫得模棱兩可后面所有的度量、工具、評審全都失去了依據(jù)。那原則怎么定通常的做法是召集核心開發(fā)一起梳理。先讓每個人列出“最近半年最讓你頭疼的代碼問題”然后把這些問題歸類抽取出共性的根因再把根因轉(zhuǎn)成否定句式就是一條原則。比如很多人都提到“每次改動某個基礎(chǔ)模塊都會連帶掛掉好幾個服務(wù)”那對應(yīng)的原則就是“基礎(chǔ)模塊禁止反向依賴業(yè)務(wù)模塊變更基礎(chǔ)模塊必須經(jīng)過架構(gòu)評審”。用團隊自己的痛點反推原則比架構(gòu)師閉門造車寫出來的原則接地氣得多也更容易被認同和執(zhí)行。2.2 機制治理動作如何嵌入日常原則定了之后需要有機制來保證原則被執(zhí)行。機制就是回答“誰來查”“什么時候查”“違反了怎么辦”這些問題。常見的機制包括架構(gòu)評審、變更委員會、技術(shù)債登記、定期架構(gòu)巡檢等。但機制設(shè)計有一個非常關(guān)鍵的原則要嵌入現(xiàn)有的研發(fā)流程而不是另起一套獨立流程。如果你讓開發(fā)在提測、上線、復盤之外再多走一套“架構(gòu)審批”那基本沒人會配合你即便配合也是走形式。我在后面第3節(jié)會專門展開講機制怎么設(shè)計這里先提一個總綱機制要分層、分場景讓80%的普通變更感受不到治理的存在只對20%的高風險變更啟動約束。這才是治理機制設(shè)計的核心心法。2.3 度量沒有數(shù)字就沒有管理度量是架構(gòu)治理里最容易做歪、但也最有杠桿效應(yīng)的一環(huán)。沒有度量的治理全靠人肉評審來發(fā)現(xiàn)問題效率太低而且不同評審人的標準還不一致。有了度量你才能回答“系統(tǒng)當前的架構(gòu)健康狀況如何”“相比上個季度是變好了還是變差了”這兩個終極問題。但度量的坑也特別多。最常見的問題是“度量變成KPI之后大家開始刷數(shù)據(jù)”。關(guān)于度量指標的選取和閾值設(shè)定我留在第4節(jié)專門講因為這塊值得單獨花篇幅。2.4 工具把治理動作自動化最后是工具。工具的作用不是替代人而是把那些重復、機械、可以自動判斷的檢查交給機器讓人只關(guān)注需要判斷力的事情。依賴關(guān)系分析工具、圈復雜度檢測工具、API兼容性檢查工具、架構(gòu)守護測試這些都是架構(gòu)治理常用的工具手段。特別是架構(gòu)守護測試的理念很值得推廣——把架構(gòu)原則寫成自動化測試代碼跑在CI流水線里每次提交代碼自動檢查違反原則的構(gòu)建直接失敗。這一招能讓治理從“偶爾查一次”變成“每次提交都查”效果是質(zhì)的飛躍。工具選型上不需要一上來就上很重的商業(yè)平臺。很多場景下開源的依賴分析工具加上你自定義的幾個腳本已經(jīng)能覆蓋80%的檢查需求。工具的價值在于連續(xù)性不在于功能數(shù)量多。3. 從評審到看護治理機制怎么設(shè)計才不流于形式這一節(jié)是重點我講一下治理機制具體怎么落地。很多團隊的問題不是沒有機制而是機制走了形式評審會開了但沒人認真看架構(gòu)委員會成立了但從不否決任何方案技術(shù)債登記了但再也沒有然后。所以機制設(shè)計的核心是想辦法讓每個動作都能產(chǎn)生真實反饋。3.1 分層級評審讓80%的變更暢通無阻只卡關(guān)鍵節(jié)點我比較推崇的機制是“三分法”的變更分層。第一層是日常變更。比如普通業(yè)務(wù)接口的新增、內(nèi)部實現(xiàn)的調(diào)整、非核心模塊的小重構(gòu)這些變更不影響全局架構(gòu)不需要任何額外評審開發(fā)自測通過、代碼評審通過就可以正常走發(fā)布流程。這層變更如果也卡評審治理就成了瓶頸大家很快就會對治理產(chǎn)生抵觸情緒。第二層是跨模塊變更。比如一個接口的協(xié)議變更影響了多個調(diào)用方或者一個新功能涉及三個以上服務(wù)的協(xié)同修改這種變更需要模塊owner參與評審重點確認跨模塊的接口設(shè)計和數(shù)據(jù)流轉(zhuǎn)是否合理。第三層是架構(gòu)級變更。比如引入新的中間件、新增一個微服務(wù)、核心模塊的重大重構(gòu)、基礎(chǔ)設(shè)施的技術(shù)選型替換這些變更必須提交架構(gòu)委員會評審。評審會要討論的不只是方案本身還要評估它對現(xiàn)有架構(gòu)的影響面、對運維體系的沖擊、對團隊技能的要求。三層分完之后你會發(fā)現(xiàn)真正需要架構(gòu)師投入精力的其實只有第三層。但這一層一定要把好關(guān)因為架構(gòu)級變更的風險是最大的也是最難回退的。3.2 例外機制治理不是一刀切再好的原則也會遇到特殊情況。業(yè)務(wù)催得急、技術(shù)方案短期妥協(xié)、遺留系統(tǒng)的歷史包袱太重這些時候強行要求合規(guī)只會逼著團隊想辦法繞開治理。一個成熟的治理機制必須包含例外通道。我的做法是“例外申請自動到期”。當團隊認為當前變更確實需要臨時違反某條架構(gòu)原則時可以發(fā)起例外申請說明理由、影響范圍、預(yù)計恢復時間。例外申請不是審批通過就完了它會自動記錄到技術(shù)債清單里并且設(shè)置到期時間。到期之前團隊必須給出處理方案——徹底解決、或者申請延期。這樣既給了業(yè)務(wù)靈活性又讓每一個例外都暴露在陽光下不會變成永久性債務(wù)。這個機制推行時最需要注意的是例外申請的審批不能太松否則所有人都會走例外通道原則就形同虛設(shè)了。我一般要求例外必須由架構(gòu)師和模塊Owner雙方確認并且一個團隊同時存在的活躍例外不超過五個。如果超過這個數(shù)說明原則本身可能有問題需要重新審視而不是繼續(xù)開例外。3.3 巡檢節(jié)奏按周、按月、按季度分別看什么治理動作要有節(jié)奏感不能想起來才查一下。我常用的節(jié)奏是這樣安排的每周做一次自動化檢查結(jié)果回顧看本周有沒有新增的架構(gòu)違規(guī)如果有立即定位是在哪個變更引入的盡快處理。這個動作最好由工具自動產(chǎn)出報告人工只需要掃一眼。每月做一次人工巡檢關(guān)注工具查不出來的問題比如模塊職責是否開始模糊、接口粒度是否合理、團隊對架構(gòu)的理解是否出現(xiàn)偏差。這種巡檢不需要很正式約上幾個核心開發(fā)花半天時間過一遍最近的架構(gòu)相關(guān)變更聊一聊感受就行。每個季度做一次正式的健康度評估基于度量指標和季度內(nèi)的治理記錄輸出一份架構(gòu)健康度報告匯報給技術(shù)管理層。這份報告要有結(jié)論——系統(tǒng)當前處于什么狀態(tài)、哪些問題必須在下個季度解決、需要什么資源支持。季度報告的目的不只是向上匯報更是為了讓技術(shù)團隊自己有清晰的方向感。我見過不少團隊平時不覺得架構(gòu)有問題一到季度報告時候才發(fā)現(xiàn)積累了十幾個架構(gòu)債這才意識到治理的價值。3.4 評審會的形式感避免變成“過場會”架構(gòu)評審會是最容易形式化的場景。我的經(jīng)驗是評審會絕對不能變成方案宣講會。方案宣講會是什么樣的開發(fā)者做了一堆PPT評委們邊聽邊點頭最后說一句“整體不錯注意一下XX細節(jié)”就結(jié)束了。這種會開一百次也不會產(chǎn)生治理價值。有效的架構(gòu)評審會應(yīng)該提前把材料發(fā)給評委讓評委在會前花時間看并給出初步意見。開會的時候不再花時間講背景和整體設(shè)計只討論分歧點和風險點大家直接開炮。如果一場評審會超過一小時那說明會前準備不到位要么是材料寫得不夠清楚要么是評委沒有提前看。評審會結(jié)束必須有明確的結(jié)論通過、有條件通過、打回重做三種結(jié)論不能模糊。有條件通過的一定要列出具體條件是什么、由誰跟進、什么時候復查不能含糊帶過。這些細節(jié)看起來是流程問題其實決定了治理是否有效。一場不痛不癢的評審會比不開還糟糕因為它消耗了所有人的時間還給大家留下“架構(gòu)評審就是走流程”的負面印象。要扭轉(zhuǎn)這個印象只需要做到一條認真開好每一次評審會讓每個參會的人都覺得這個會值得花時間。4. 量化不等于僵化架構(gòu)治理指標怎么定才有用指標是治理的眼睛。但指標也是雙刃劍——用好了能驅(qū)動改進用歪了會帶來一系列反噬。這一節(jié)我把指標設(shè)計的思路和一些常見坑都說透。4.1 核心指標集從依賴、復雜度、一致性三個維度入手不要追求大而全的指標體系和華麗的度量看板。我覺得指標只要能覆蓋三個維度就夠了依賴健康度、模塊清晰度、變更一致性。依賴健康度常用的是這幾種指標循環(huán)依賴個數(shù)這個是硬指標正常應(yīng)該為零反向依賴數(shù)量即基礎(chǔ)模塊被哪些上層模塊依賴、以及基礎(chǔ)模塊是否反向依賴了上層模塊平均扇入扇出單個服務(wù)的調(diào)用方數(shù)量和依賴方數(shù)量過高就要警惕。這些指標用來回答一個問題系統(tǒng)的依賴關(guān)系是否還處于可控狀態(tài)。模塊清晰度衡量的是代碼實現(xiàn)跟架構(gòu)設(shè)計的偏離程度。最常見的手段是“架構(gòu)分層合規(guī)率”按架構(gòu)設(shè)計文檔中定義的分層規(guī)則和模塊邊界掃描實際代碼的包結(jié)構(gòu)、依賴方向算出有多少代碼違反了設(shè)計邊界。這個指標最有價值的地方在于它能直接定位到具體的包和類讓治理動作能落到具體代碼上而不是停留在“全局比較健康”這種模糊判斷。變更一致性關(guān)注的是架構(gòu)被破壞的頻率、例外申請的數(shù)量和存續(xù)時長、核心模塊的變更頻率和變更集中度。如果一個核心領(lǐng)域模塊每周被十幾個非核心需求反復改動那很大概率說明模塊邊界劃分出了問題或者模塊的擴展方式不夠合理需要介入而不是繼續(xù)放任。4.2 Goodhart陷阱指標變成目標就會失去意義指標設(shè)計最大的坑就是Goodhart定律說的事情當一個指標成為目標它就不再是個好指標了。我見過一個很典型的例子。某團隊為了控制服務(wù)數(shù)量定了一個指標“單服務(wù)最大接口數(shù)不超過20個”。結(jié)果怎么樣開發(fā)確實不再往一個服務(wù)里加接口了他們學會了把接口改個名字塞進另一個服務(wù)或者在網(wǎng)關(guān)層做轉(zhuǎn)發(fā)直接繞過了統(tǒng)計。指標好看了架構(gòu)卻更亂了。所以我在設(shè)計指標的時候有一條基本原則凡是能被人為“優(yōu)化”但實際沒有改善架構(gòu)的指標都要警惕。反制的方法是組合使用指標不讓單一指標承擔過大的壓力。比如“接口數(shù)”要和“服務(wù)的平均依賴數(shù)”“跨服務(wù)調(diào)用占比”一起看防止通過拆分服務(wù)來刷單一指標。另外指標數(shù)據(jù)最好由工具自動采集不要依賴人工填寫人工填寫必然有水分。還有一個很重要的心法指標的作用是定位問題而不是考核團隊。如果你把架構(gòu)指標納入績效考核團隊的理性選擇就是美化數(shù)字而不是真正改進。我見過最好的用法是月度架構(gòu)健康報告出來后大家關(guān)注的是“這個季度環(huán)比改善了還是惡化了”“惡化出現(xiàn)在哪里”而不是“誰的數(shù)字最差”。指標是手電筒不是鞭子。4.3 閾值設(shè)定的方法論從歷史數(shù)據(jù)反推而不是拍腦袋閾值怎么定很多團隊拍腦袋定一個“圈復雜度不能超過10”結(jié)果發(fā)現(xiàn)大量存量代碼都在15以上新代碼倒是符合了但架構(gòu)沒有變好。正確的做法是先測量、再定標。拿到一個系統(tǒng)之后先讓工具跑一遍全量掃描把當前所有相關(guān)指標的基礎(chǔ)數(shù)據(jù)拉出來算出分位數(shù)。比如依賴數(shù)量看看現(xiàn)在的服務(wù)里最大的扇入是多少、最小的是多少、中位數(shù)是多少然后以“中位數(shù)附近的20%不能超過、當前最差的一批在未來兩個季度逐步收斂”這種思路來定閾值。也就是說閾值是動態(tài)演進的——第一季度的目標可以是“不再新增超過當前最差水平的依賴”第二季度可以是“最差的20%全部降低30%”第三季度再往更嚴格的方向收斂。這種漸進式的指標定法比一刀切要現(xiàn)實得多也更容易得到開發(fā)團隊的配合。畢竟沒有人愿意突然被要求把自己維護了三年的模塊在一周內(nèi)整改到完全合規(guī)這根本不現(xiàn)實。但如果你說的是“我們先用三個月停止惡化再用一個季度完成一輪集中的債務(wù)削減”大家的接受度會高很多。4.4 度量的最終出口一定要連接到?jīng)Q策指標最后必須連接到?jīng)Q策否則就是純展示。什么叫連接到?jīng)Q策就是有了這個指標你會做出一個跟之前不一樣的判斷或動作。舉個例子如果你發(fā)現(xiàn)某個服務(wù)的循環(huán)依賴數(shù)量在一個月內(nèi)從2漲到了8那你的決策就是立即召集相關(guān)模塊的owner開一次對齊會找出引入循環(huán)依賴的那幾次變更逐個解決。再比如季度報告顯示“核心領(lǐng)域模塊的被依賴度持續(xù)升高”那你的決策就是拒絕在這個模塊里繼續(xù)加新功能要求需求方走新的拆分方案。指標只有能驅(qū)動這樣的具體動作它才算是治理體系的有機組成部分否則就只是墻上的一張美化圖表。我見過太多團隊做了很漂亮的架構(gòu)看板但大家只是偶爾看一眼然后什么都不發(fā)生這種度量就是純成本。5. 架構(gòu)治理真正的難題協(xié)同、權(quán)力和激勵很多做架構(gòu)治理的人容易把注意力全放在工具和指標上覺得有一套自動化的守護系統(tǒng)就萬事大吉了。但真正做過一段時間的人會告訴你最難的從來不是技術(shù)問題而是協(xié)同問題。5.1 架構(gòu)師沒有“命令權(quán)”怎么推進治理落地先說一個現(xiàn)實在很多公司里架構(gòu)師這個角色有責無權(quán)。你要對架構(gòu)的健康度負責但你并沒有直接指揮開發(fā)團隊的權(quán)力也不掌握團隊的績效和晉升。這種情況下推行治理如果全靠“說服”和“人情”一定走不遠。我的經(jīng)驗是治理要獲得實際推動力必須綁定一些不可繞過的節(jié)點。最有效的是發(fā)布環(huán)節(jié)。如果架構(gòu)守護檢查是發(fā)布流水線的一環(huán)代碼不通過就發(fā)不上去那么不需要任何人去“說服”開發(fā)他們也會主動修復架構(gòu)問題。這就是把技術(shù)手段當作治理權(quán)的一種變通。另一個有效的節(jié)點是項目立項和技術(shù)選型。任何新項目、新系統(tǒng)或重大的技術(shù)改造必須過架構(gòu)評審否則不予批準資源。這兩條卡住之后架構(gòu)師在關(guān)鍵節(jié)點上就有了實際的控制力而不只是靠一張嘴推動。當然這里要小心不能把治理變成“卡人”的工具。架構(gòu)師的價值是幫團隊把事情做成而不是增加阻力。所以我推動治理的時候總會強調(diào)一個導向架構(gòu)守護是在幫大家“提前攔下未來要還的債”而不是在挑毛病。帶治理視角的評審會討論的問題是怎么設(shè)計才能讓后續(xù)的開發(fā)更輕松、發(fā)布更安全、維護更簡單而不是純從理論上評判對錯。5.2 讓業(yè)務(wù)方也從治理中受益架構(gòu)治理如果只讓技術(shù)團隊受益業(yè)務(wù)方是沒有動力配合的。但如果你能證明治理和業(yè)務(wù)目標直接相關(guān)局面就會完全不一樣。舉個例子某次業(yè)務(wù)提了一個快速上線的新需求但方案需要繞過正常的服務(wù)邊界。如果架構(gòu)師只說“這不符合架構(gòu)原則”業(yè)務(wù)方會覺得很抽象。但如果你換一個說法“這個改法會讓下單接口多一次跨服務(wù)調(diào)用鏈路響應(yīng)時間預(yù)計增加80毫秒并且后續(xù)每次改促銷邏輯都得同時改兩個服務(wù)同步發(fā)版線上出問題的概率會明顯上升。”業(yè)務(wù)方立刻能聽懂而且大概率會主動配合你調(diào)整方案。把架構(gòu)問題翻譯成業(yè)務(wù)語言是架構(gòu)師推動治理的一項關(guān)鍵能力。響應(yīng)時間、故障率、上線效率、維護成本這些才是業(yè)務(wù)方真正關(guān)心的東西。每一次治理動作你都應(yīng)該嘗試用業(yè)務(wù)可感知的語言來描述收益。時間長了業(yè)務(wù)方會逐漸形成一種心智架構(gòu)治理不是在給他們添麻煩而是在保護業(yè)務(wù)的穩(wěn)定性和交付效率。5.3 獎勵比懲罰更有效正反饋循環(huán)怎么建治理的持續(xù)推進需要正反饋。如果團隊做了半年的架構(gòu)改進業(yè)務(wù)沒有任何感知開發(fā)自己也感覺不到明顯變化那這個治理運動遲早會熄火。所以要設(shè)計一些能快速見效的早期目標讓大家嘗到甜頭。我常用的做法是第一個季度不追求大而全的治理而是選一個痛點最集中的模塊做專項整治。比如一個典型的場景是訂單服務(wù)的調(diào)用方太多每次改動都要協(xié)調(diào)五六個團隊聯(lián)調(diào)。一個季度集中做一輪接口收斂和服務(wù)拆分把調(diào)用方從20個降到了8個。這個改進做完之后最直接的收益是訂單模塊的聯(lián)調(diào)溝通成本明顯下降發(fā)布次數(shù)可以更頻繁測試回歸的范圍也小了。開發(fā)同學自己會感覺到“現(xiàn)在改東西明顯輕快多了”這種感受比任何KPI都有說服力。治理推進者還要注意及時廣播戰(zhàn)績。每次專項整治完成寫一篇簡要的復盤發(fā)到團隊群說清楚改了什么、帶來了什么收益、過程中踩了什么坑。這既是知識沉淀也是給參與同學的公開認可能形成一個正向的循環(huán)。治理不是一次性的運動它需要持續(xù)的小勝利來維持士氣。6. 從現(xiàn)狀出發(fā)的落地路線新系統(tǒng)與存量系統(tǒng)的治理策略完全不同很多人問架構(gòu)治理應(yīng)該從什么時候開始做我的回答是新系統(tǒng)從第一天就做存量系統(tǒng)從盤點開始做。這兩種場景的治理策略完全不同我分開說。6.1 新系統(tǒng)在第一天就植入治理基因新項目的優(yōu)勢是還沒有歷史包袱原則和工具的落地成本最低。但新項目也有劣勢就是團隊會覺得“系統(tǒng)剛搭起來哪有什么架構(gòu)問題”治理很容易被擱置到“以后再說”。我的建議是新項目在啟動階段就做三件事。第一把架構(gòu)原則寫進項目交接文檔并且讓工具掃描從第一個提交就開始跑起來哪怕當前代碼量很小也要把規(guī)則建立起來。第二明確架構(gòu)評審的分層標準項目初期就定義清楚哪些變更算架構(gòu)級變更哪些是日常變更確保第一個微服務(wù)的拆分、第一個中間件的引入都走評審流程。第三選定架構(gòu)治理工具鏈把依賴分析、復雜度檢查、架構(gòu)守護測試全部配置在CI流水線里。工具從第一天就接入后面就沒有任何“歷史債”需要清理。新項目治理的最大價值是“未病先治”成本最低、效果最好。很多團隊嫌麻煩覺得項目剛開始沒必要搞這些結(jié)果往往是系統(tǒng)上線半年后架構(gòu)已經(jīng)開始混亂才想起來要做治理這時候再返工成本比一開始就做高好幾倍。6.2 存量系統(tǒng)先做架構(gòu)盤點再啟動治理存量系統(tǒng)的治理最忌諱的是直接上全套指標和工具然后宣布“從今天起我們要嚴格執(zhí)行架構(gòu)規(guī)范”。這種做法的后果是工具掃出一堆歷史違規(guī)團隊一看要改的代碼量太大直接擺爛治理運動還沒開始就結(jié)束了。正確的姿勢是先做架構(gòu)盤點和基線固化。用工具對系統(tǒng)做一次全量掃描輸出當前的依賴關(guān)系圖、模塊邊界、復雜度分布、關(guān)鍵代碼路徑。不要指望一次盤點就把所有問題都弄清楚重點是先建立“當前系統(tǒng)的真實狀態(tài)”這個基線。盤點的過程其實也是團隊重新理解自己系統(tǒng)的過程很多人做完盤點才發(fā)現(xiàn)原來系統(tǒng)里已經(jīng)藏了這么多自己都不知道的依賴關(guān)系。然后做債務(wù)分級。把盤點出來的問題分為三類影響線上穩(wěn)定性的必須立即處理影響迭代效率的安排在一個季度內(nèi)集中處理純粹的規(guī)范性問題作為長期優(yōu)化逐步推進。一定要優(yōu)先處理影響線上穩(wěn)定性的問題因為這類問題最容易獲得業(yè)務(wù)方的支持。用一次線上故障的真實案例來推動治理比開十次治理宣貫會都管用。6.3 前三個月的推進節(jié)奏從輕到重、小步快跑第一到第四周完成工具接入和架構(gòu)盤點輸出基線報告選定一個痛點模塊做試點。這個階段的目標不是做得多而是搭好機制。第五周到第八周試點模塊的專項整治開始同時日常的自動化檢查全面運行每周回顧一次違規(guī)報告。這個階段的重要節(jié)點是試點模塊的改進初見成效讓大家感受到治理確實有用。第九周到第十二周把試點經(jīng)驗固化到流程里更新架構(gòu)原則和評審標準然后向全系統(tǒng)推廣。這個階段要特別注意推廣的力度要“由輕到重”先從最容易接受的新模塊開始再逐步覆蓋到核心老模塊。前三個月最容易犯的錯是用力過猛。我曾經(jīng)見過一個團隊第一周就要求所有模塊圈復雜度必須降到10以下結(jié)果光梳理存量代碼就花了兩個星期什么治理動作都沒做最后全盤擱淺。我現(xiàn)在特別信奉一個原則治理的節(jié)奏要慢到讓團隊消化得動快到來不及產(chǎn)生新的壞味道。這中間的火候只能靠一線的實際情況來把握。7. 關(guān)于架構(gòu)治理我最后想分享的幾點真實體會架構(gòu)治理這件事做的時間越長越覺得它像一門“平衡的藝術(shù)”。它不是簡單地把規(guī)則定下來、把工具跑起來就完事而是要持續(xù)在各種力量的拉扯中找平衡。一是要在約束和效率之間找平衡。規(guī)則太多太細會拖垮研發(fā)節(jié)奏最后大家把所有規(guī)則都當成形式整體約束力反而下降。規(guī)則太少太粗又起不到防護作用。所以原則定完之后要定期回訪團隊問一句“這些規(guī)則有沒有哪條是你們覺得沒意義的”。如果某條規(guī)則連續(xù)三個月沒有攔截到任何問題可能它不是保護了架構(gòu)而是已經(jīng)被人悄悄繞過了需要重新評估。二是要在自動化守護和人工判斷之間找平衡。工具能查循環(huán)依賴但查不出模塊職責的模糊能統(tǒng)計接口數(shù)量但判斷不了接口粒度合不合理。架構(gòu)治理配比合理的話自動化工具能解決70%的問題剩下30%必須靠架構(gòu)師的經(jīng)驗和判斷力。不要試圖把所有事情都自動化那是自欺欺人。三是要在“當下”和“未來”之間找平衡。治理不能只盯著當下系統(tǒng)的健康度也要關(guān)注系統(tǒng)未來能否持續(xù)演進。一個當前看起來很健康、但核心模塊已經(jīng)龐大到無法擴展的系統(tǒng)比一個當前有一些技術(shù)債、但核心模塊邊界清晰、易于拆分的系統(tǒng)更危險。看治理效果要放在六到十二個月的時間跨度上來評價不能只看當下的數(shù)字。如果你正要開始推動架構(gòu)治理我的建議是從一個小切口開始先選一個你最擔心的模塊把工具跑起來把自動化檢查建起來把一個專項整治做起來。不要試圖在第一周就建完所有的體系治理是慢功夫但它一旦跑起來會像一個自動運轉(zhuǎn)的健康衛(wèi)士持續(xù)守護住架構(gòu)設(shè)計的初衷。