不是設(shè)計(jì)出來的)
做了快十年程序員見過不少架構(gòu)——有的簡潔到讓人覺得「這也算架構(gòu)」有的精巧到讓人讀不懂。好的架構(gòu)不是設(shè)計(jì)出來的是在每個(gè)階段做了正確的決策才長出來的。四階段框架我把一個(gè)項(xiàng)目的演進(jìn)拆成四個(gè)階段能跑 → 跑得準(zhǔn) → 跑得穩(wěn) → 跑得快。它們是遞進(jìn)的時(shí)間線每進(jìn)入一個(gè)新階段上一個(gè)階段的能力還得保持。但每個(gè)階段的核心矛盾不同你要盯住的東西也不同。階段核心問題架構(gòu)焦點(diǎn)能跑這東西能不能 work簡單優(yōu)先砍掉一切不必要的跑得準(zhǔn)結(jié)果對嗎業(yè)務(wù)驅(qū)動用數(shù)據(jù)驗(yàn)證跑得穩(wěn)炸了怎么辦引入復(fù)雜度容錯(cuò)、監(jiān)控、灰度跑得快扛得住嗎只在瓶頸處動手優(yōu)化這個(gè)框架有一個(gè)大前提項(xiàng)目不確定性高。你不知道要做什么、不知道能不能做成、不知道用戶會不會用。這時(shí)候階段演進(jìn)是攢認(rèn)知的過程一步到位等于盲人摸象。但如果需求很明確——業(yè)務(wù)方已經(jīng)把需求拆到字段級別數(shù)據(jù)量、并發(fā)量都有預(yù)估——你還按「能跑」來就是浪費(fèi)大家時(shí)間。確定性高的項(xiàng)目前期設(shè)計(jì)要重該想清楚的要想清楚該預(yù)留的擴(kuò)展點(diǎn)要預(yù)留好。區(qū)別不在于原則本身在于每條原則的權(quán)重0→1 探索型確定性交付型簡單優(yōu)先★★★ 死守復(fù)雜度是負(fù)債★★ 保持節(jié)省但要預(yù)留擴(kuò)展點(diǎn)業(yè)務(wù)驅(qū)動★★★ 業(yè)務(wù)反饋驗(yàn)證方向★★★ 同樣重要但業(yè)務(wù)目標(biāo)是已知的先跑通再優(yōu)化★★★ 先攢認(rèn)知★ 需求已經(jīng)清楚設(shè)計(jì)時(shí)就可以優(yōu)化核心不變做當(dāng)下信息量下最合理的決策。信息少的時(shí)候不瞎猜信息多的時(shí)候不偷懶。能跑先證明想法不成立「能跑」階段最容易犯的錯(cuò)是想太多。表結(jié)構(gòu)還沒定就開始琢磨分庫分表流量還沒來就把消息隊(duì)列、微服務(wù)、K8s 全套安排上。這個(gè)階段只有一個(gè)目標(biāo)用最小的成本證明這個(gè)方向值得繼續(xù)。怎么做三個(gè)字砍、硬、短??晨彻δ?。一個(gè) MVP 需要的功能比你想象中少得多。用戶管理先用 admin 賬號頂著。權(quán)限先不做。通知先不做。硬硬編碼可以寫死配置可以。別在「能跑」階段追求靈活性靈活性是給「跑得穩(wěn)」階段準(zhǔn)備的。短代碼短文件少依賴輕。一個(gè)能跑的原型1000 行代碼能搞定的事不要搞成 10 個(gè)微服務(wù)。「簡單優(yōu)先」不是偷懶——每多引入一個(gè)組件就多一個(gè)可能出錯(cuò)的點(diǎn)就多一份調(diào)試時(shí)的茫然。簡單意味著更少意外。案例早年做過一個(gè)數(shù)據(jù)同步工具技術(shù)選型時(shí)在 Spark Streaming 和 Flink 之間糾結(jié)了很久。最后兩個(gè)都沒用——用 shell cron 先跑了一周發(fā)現(xiàn)瓶頸在源端 API 限流跟計(jì)算引擎沒關(guān)系。如果直接上流處理框架這個(gè)真相要等到上線后才發(fā)現(xiàn)而那時(shí)已經(jīng)搭進(jìn)去一整套基礎(chǔ)設(shè)施。退出信號當(dāng)你開始問「這樣寫對不對」而不是「能不能跑」的時(shí)候該進(jìn)入下一階段了。跑得準(zhǔn)別自己騙自己「能跑」證明了能做出來。「跑得準(zhǔn)」要證明的是做出來的東西是對的。這個(gè)階段技術(shù)人最容易掉進(jìn)的坑用技術(shù)指標(biāo)替代業(yè)務(wù)指標(biāo)。QPS 上去了延遲下來了覺得自己干得不錯(cuò)。但業(yè)務(wù)側(cè)說「數(shù)據(jù)對不上」。「跑得準(zhǔn)」的核心是把業(yè)務(wù)結(jié)果當(dāng)成唯一的驗(yàn)證標(biāo)準(zhǔn)。不是單元測試過了就算對不是代碼 review 過了就算對——是業(yè)務(wù)方看了結(jié)果點(diǎn)頭才算對。具體怎么做端到端對賬不是中間環(huán)節(jié)的日志對得上是源端和終端的數(shù)對得上。中間環(huán)節(jié)再多都對兩頭差一條就是不準(zhǔn)。業(yè)務(wù)方驗(yàn)收不要自己定了正確標(biāo)準(zhǔn)然后自己做裁判讓業(yè)務(wù)方來驗(yàn)收。別迷信測試測試覆蓋的是你知道的邏輯線上出問題往往是你不知道的邏輯。測試只是兜底不是驗(yàn)證。退出信號業(yè)務(wù)方不再來找你對賬了。跑得穩(wěn)該花的復(fù)雜度要花到了這個(gè)階段系統(tǒng)已經(jīng)在跑了、結(jié)果也對了。但你還睡不踏實(shí)。這才是真正開始談架構(gòu)的階段。前面的「能跑」和「跑得準(zhǔn)」是在攢認(rèn)知——你知道了系統(tǒng)的瓶頸在哪、業(yè)務(wù)的核心鏈路是什么、什么數(shù)據(jù)不能丟、什么延遲不能超?!概艿梅€(wěn)」的核心矛盾是你要引入復(fù)雜度??煽啃缘植荒馨严到y(tǒng)搞死。幾個(gè)必須花的復(fù)雜度容錯(cuò)。任何操作都要想「失敗了怎么辦」。重試回滾降級不是每個(gè)環(huán)節(jié)都要三樣都做但每個(gè)環(huán)節(jié)至少要有一個(gè)兜底路徑。可觀測。日志、指標(biāo)、告警這三樣是「跑得穩(wěn)」的基礎(chǔ)建設(shè)。沒有可觀測性系統(tǒng)炸了你都不知道炸在哪?;叶?金絲雀。敢直接全量切說明你對系統(tǒng)還不夠了解。灰度發(fā)布不是膽小是給自己留退路。但也有不能花的復(fù)雜度不要為了「萬一」做架構(gòu)。一個(gè)日活幾百的內(nèi)部系統(tǒng)上微服務(wù)、分庫分表、多活容災(zāi)——這些復(fù)雜度花出去帶來的不是可靠性是維護(hù)負(fù)擔(dān)。案例一個(gè)數(shù)據(jù)入湖鏈路單機(jī)跑沒問題但數(shù)據(jù)量上來后就怕掛。方案是加 checkpoint 機(jī)制——掛了能從斷點(diǎn)續(xù)跑不用從頭來。多寫了幾十行代碼換來的是凌晨三點(diǎn)不用爬起來手動重跑。退出信號你能安心睡覺了。跑得快別提前優(yōu)化性能優(yōu)化有一條鐵律只在瓶頸處動手。「提前優(yōu)化」是人性的問題——你知道了某個(gè)地方可以更快手就癢。你剛寫完一段代碼腦子里已經(jīng)在想「這個(gè)循環(huán)能不能少遍歷一次」。忍住?!概艿每臁沟恼_姿勢先 profiling再動手。你不知道瓶頸在哪之前所有的優(yōu)化都是在正確的地方浪費(fèi)時(shí)間。用火焰圖用慢查詢?nèi)罩居?metrics——找到真正的熱點(diǎn)。優(yōu)化有成本。代碼更快的代價(jià)往往是更難讀。一個(gè)for循環(huán)變成三個(gè)map/filter鏈?zhǔn)秸{(diào)用快了 5% 但三個(gè)月后沒人看得懂。這個(gè)買賣做不做看 5% 在那個(gè)場景下值不值?;A(chǔ)設(shè)施優(yōu)先。很多性能問題不靠改代碼解決——加個(gè)緩存、加個(gè)索引、調(diào)個(gè)連接池參數(shù)——效果比摳代碼邏輯大得多。案例一個(gè)數(shù)據(jù)查詢接口慢第一反應(yīng)是優(yōu)化 SQL折騰了半天。后來發(fā)現(xiàn)瓶頸不在 SQL在每次查詢都要從 S3 拉文件。加了本地緩存延遲從秒級降到毫秒級。退出信號沒人再抱怨慢了。原則之間的關(guān)系簡單優(yōu)先、業(yè)務(wù)驅(qū)動、先跑通再優(yōu)化——這三條原則貫穿四階段但不是每條都平等地作用于每個(gè)階段。能跑跑得準(zhǔn)跑得穩(wěn)跑得快簡單優(yōu)先★★★ 死守★★ 保持★ 讓位于可靠性★★ 克制優(yōu)化欲業(yè)務(wù)驅(qū)動★ 先跑再說★★★ 唯一標(biāo)準(zhǔn)★★ 業(yè)務(wù)鏈路優(yōu)先★★ 優(yōu)化業(yè)務(wù)熱點(diǎn)先跑通再優(yōu)化★★★ 就是 MVP—★ 穩(wěn)定了再談性能★★★ 但別提前三條原則在你心里不是一個(gè)固定權(quán)重。不同階段的優(yōu)先級不一樣這才是「權(quán)衡」的真正含義。收尾架構(gòu)能力不是你畫了多少張圖、用了多少種中間件決定的。是你在正確的時(shí)間做了正確的退讓決定的。「能跑」時(shí)你退讓了完美「跑得準(zhǔn)」時(shí)你退讓了技術(shù)自負(fù)「跑得穩(wěn)」時(shí)你退讓了簡單「跑得快」時(shí)你退讓了優(yōu)化欲。每個(gè)階段都有一個(gè)你死守的東西和一個(gè)你主動放下的東西。知道什么時(shí)候該守什么、放什么比知道多少種設(shè)計(jì)模式都重要。架構(gòu)不是一次性的決策是持續(xù)四階段的循環(huán)。下一個(gè)需求來了又是從「能跑」開始。