架構設計原則#
架構設計的本質是在「不確定性」中做選擇。編程有明確的語法和邏輯,結果是確定的;但架構設計面對的是多種可能性,不同的選擇都可能可行。
本章介紹三條核心原則,幫助架構師在不確定性中做出更好的選擇。
原則一:合適優於業界領先#
宣言:合適優於業界領先
為什麼「領先」往往失敗#
技術人員都有追求卓越的情結,想要設計出媲美 Google、阿里的架構。但現實是,大部分這樣的嘗試都以失敗告終。
失敗原因一:將軍難打無兵之仗
大公司一個小系統就有幾十人維護,而大部分公司整個團隊可能就十幾人。沒那麼多人,卻想幹那麼多活。
失敗原因二:羅馬不是一天建成的
業界領先的方案是經過多年發展、無數踩坑才逐步完善的。沒有那麼多積累,卻想一步登天。
失敗原因三:冰山下面才是關鍵
領先方案往往是被業務「逼」出來的。GFS 誕生於 Google 而非 Microsoft,是因為 Google 有那麼龐大的資料處理需求。沒有卓越的業務場景,卻幻想靈光一閃成為天才。
很多 BAT 出來的架構師到了小公司做不出成績,就是因為失去了大公司的平台、資源、積累,生搬硬套大公司的做法。
「合適」的標準#
真正優秀的架構是在當前的人力、條件、業務等約束下設計出來的,能夠:
- 合理整合現有資源
- 發揮出最大功效
- 能夠快速落地
原則二:簡單優於複雜#
宣言:簡單優於複雜
複雜性的兩個來源#
1. 結構的複雜性
組件越多,關係越複雜,問題就越多:
| 組件數 | 可用性(假設單組件 90%) | 問題 |
|---|---|---|
| 3 個 | 72.9% | - |
| 5 個 | 59% | 相比 3 個下降 13% |
結構複雜的三大問題:
- 可用性下降:組件越多,故障概率越高
- 變更困難:一個組件改動會影響所有關聯組件
- 定位困難:出問題時要逐一排查,可能還互相影響
2. 邏輯的複雜性
單個組件承擔太多功能,同樣會帶來問題。想像把電商的所有功能(商品、訂單、支付、物流、客服)都放在一個組件中:
- 程式碼量龐大,clone 一次要 30 分鐘
- 幾十人維護同一套程式碼,互相衝突
- 需求堆積,分支混亂
- 一個 bug 可能導致整站崩潰
電路複雜意味著更強大,但軟件複雜卻意味著問題。區別在於:電路設計好後不再變化,而軟件需要不斷修改以適應業務發展。
KISS 原則#
Keep It Simple, Stupid!
如果簡單方案和複雜方案都能滿足需求,選擇簡單的。
範例:主備選擇方案
方案一:心跳機制實作主備切換
- 優點:簡單、易理解、好維護
- 缺點:看起來不夠「高大上」
方案二:引入 ZooKeeper 做主備決策
- 優點:ZAB 協議很優秀,看起來專業
- 缺點:引入額外複雜性,團隊可能不熟悉
如果心跳機制能滿足需求,就選心跳。不要為了看起來「專業」而引入不必要的複雜性。
原則三:演化優於一步到位#
宣言:演化優於一步到位
軟件與建築的本質差異#
| 特性 | 建築 | 軟件 |
|---|---|---|
| 主題 | 永恆 | 變化 |
| 完成後 | 結構不再改變 | 需要不斷修改 |
| 範例 | 金字塔 4000 年不變 | Windows 1.0 → 8 面目全非 |
對於建築來說,永恆是主題;對於軟件來說,變化才是主題。
演化的方法論#
軟件架構設計類似於大自然「設計」生物的過程:
適應環境 繁殖演化 環境變化
生物: ──────────→ ──────────→ ──────────→
當前環境生存 基因傳遞/淘汰 快速適應/被淘汰
滿足業務 迭代最佳化 業務變化
軟件: ──────────→ ──────────→ ──────────→
當前需求可用 最佳化/修復/去除 擴展/重構/重寫演化原則的三個要點:
- 首先:設計出來的架構要滿足當時的業務需要
- 其次:在實際應用中不斷迭代——保留優秀、修復缺陷、改正錯誤、去掉無用
- 第三:當業務變化時,架構要擴展、重構,甚至重寫
試圖一步到位設計一個「完美」架構,期望不管業務如何變化,架構都穩如磐石。這種想法會導致投入巨大、落地遙遙無期,而且很多預測都不靠譜。
實踐建議#
即使是大公司的團隊,在設計新系統時也需要遵循演化原則:
- 認真分析當前業務特點
- 明確當前面臨的主要問題
- 設計合理的架構,快速落地
- 在運行中不斷完善
- 隨著業務演化架構
三原則的優先級#
這三條原則在實踐中如何排序?
flowchart TD
A[合適原則] --> B[簡單原則]
B --> C[演化原則]
A -.- A1((首要考慮))
B -.- B1((在合適的基礎上求簡單))
C -.- C1((保持演化能力))
style A fill:#e8f5e9,stroke:#4caf50
style B fill:#e3f2fd,stroke:#2196f3
style C fill:#fff3e0,stroke:#ff9800- 合適原則最優先:脫離實際的架構毫無意義
- 簡單原則次之:在合適的前提下,越簡單越好
- 演化原則貫穿始終:時刻為未來的變化保留空間
- 先問「合不合適」
- 再問「能不能更簡單」
- 最後問「將來怎麼演化」
本章小結#
| 原則 | 宣言 | 核心思想 |
|---|---|---|
| 合適 | 合適優於業界領先 | 在約束下找最優解,不盲目追求「高大上」 |
| 簡單 | 簡單優於複雜 | 複雜帶來問題,能簡單就簡單 |
| 演化 | 演化優於一步到位 | 軟件的本質是變化,設計要為變化留空間 |