文 / Kenyon,資深軟件架構師,15年軟件開發和技術管理經驗,從程序員做到企業技術高管,專注技術管理、架構設計、AI技術應用和落地。
由於公眾號推流的原因,請在關注頁右上角加星標,這樣才能及時收到新文章的推送。
引言
大家好,我是Kenyon!上一篇文章我們聊了架構設計裏面的基本設計原則——《SOLID》,如果把架構設計比喻成是一棟大廈,那麼SOLID就是這座大廈的“地基”,後續所有的架構設計原則或者是方法都得靠它支撐的,如果沒有它的話,架構設計就會變得非常複雜和混亂。接下來今天的這篇文章,我們接着探討一下其他的一些架構的通用設計原則、方法、模式及相關要考慮的問題。
一、通用設計原則
- YAGNI (You Aren't Gonna Need It)
這個原則的核心意思就是,別搞過度的設計。我們設計的時候就老老實實的把當前必須要有的功能實現了就行了,別老想着“未來可能用得上”,就提前把不必要的功能給設計進來。
就好比在需求還不明確的時候,我們得先把眼前的業務給滿足了,別一上來就搞一堆複雜的東西。比如説微服務拆分的時候,需要拆那個就拆那個,別説為了那“可能的擴展性”,就早早地把服務給拆得七零八落的,這樣只會得不償失! - DRY (Don't Repeat Yourself)
這個原則的核心就是,別讓代碼、配置或者邏輯出現重複。我們可以通過抽象或者複用的辦法,把維護成本給降下來。
在架構層面,重複的情況可不少。像好幾個服務都實現一樣的權限邏輯,還有重複的配置管理啥的。這時候,我們就可以把公共的能力下沉到中間件或者共享服務裏,問題就解決了。 - 高內聚低耦合 (High Cohesion, Low Coupling)
這個原則説的是,模塊裏面的功能得緊密相關,這就是高內聚;模塊和模塊之間的依賴得儘量少,這就是低耦合。
比如説服務拆分的時候,得保證每個服務就負責一個單一的業務域。就像訂單服務,就只管訂單的生命週期。而且模塊之間最好通過接口來依賴,別直接依賴實現類,這樣耦合度就能降下來。 - 迪米特法則 (Law of Demeter)
這個原則講的是,一個對象得儘量少去了解其他對象的內部結構,儘量只跟自己直接的調用的類或者模塊通信。
在微服務調用的時候,如果不限制好的話,就特別容易出現問題。比如説那種鏈式調用,serviceA.getServiceB().getServiceC().doSomething() ,這樣肯定是不行的啊。我們應該通過API網關或者聚合服務,把依賴給簡化簡化。 - KISS (Keep It Simple, Stupid)
這個原則的核心就是,能設計多簡單就多簡單,別整那些不必要的複雜玩意。越簡單的系統約靠譜,也好維護,還能快速應對變化。
比如説新項目剛開始的時候,我們就選成熟又簡單的技術棧就可以了。接口設計的時候,也別過度設計參數和返回值。代碼實現的時候,優先考慮可讀性。就像那些產品的日活用户都不到1萬的創業公司,就別一上來就用什麼服務網格這樣複雜的架構了。
二、架構設計方法學
- 領域驅動設計 (DDD)
這方法的核心是以業務領域為中心,通過領域建模來指導架構設計,這裏面有聚合、實體、值對象、領域服務這些概念。
在複雜業務系統裏,像金融、電商這些領域,這樣DDD就特別適用。通過劃分限界上下文(Bounded Context),來指導微服務的拆分,讓服務邊界和業務邊界保持一致。 - 事件溯源 (Event Sourcing)
這方法的核心是,不僅保存當前的狀態,還要把所有狀態變更的事件都記錄下來。如果出現故障的時候就可以通過重放這些事件,快速地恢復系統的狀態。
像那些需要審計、追溯或者有複雜狀態管理的系統,比如交易系統、物流跟蹤系統,這樣設計就特別適合。要是再結合CQRS,還能優化讀性能呢。 - CQRS (Command Query Responsibility Segregation)
這方法的核心是把命令(就是寫操作)和查詢(就是讀操作)給分開,用不同的模型和存儲來優化它們各自的性能。
在那種讀多寫少,或者讀寫邏輯差異特別大的系統裏,就特別好用。比如説商品詳情頁,寫操作就更新數據庫,讀操作就從緩存或者搜索引擎裏獲取數據。
三、架構模式
- 六邊形架構 (Hexagonal Architecture)
這架構也叫“端口適配器模式”,我的帳號取名就是來自於它了,它的理念就是把業務邏輯和外部依賴(像數據庫、UI、第三方服務這些)都給隔離開來,通過端口(就是接口)和適配器(就是實現)來交互。
在那種需要頻繁更換外部依賴的系統裏,就特別適用。比如説我們要把數據庫從MySQL切換到PostgreSQL,就只需要把數據適配器替換一下就行。 - 洋葱架構 (Onion Architecture)
這種架構模式的核心是領域模型,外層可以依賴內層,但是內層就不可以依賴外層,這就是依賴反轉。它的層次依次是:領域模型 → 領域服務 → 應用服務 → 基礎設施層。
在那種強調業務邏輯獨立性的系統裏,就特別適合用這種架構模式,這樣假如架構某部分內容變了也能保證不影響核心業務規則。 - 整潔架構 (Clean Architecture)
這架構和洋葱架構有點像,它強調的是“依賴規則”,就是內層定義接口,外層來實現;業務邏輯不能依賴框架、數據庫或者UI。
在那種需要長期維護的大型系統裏,就特別適用,能保證代碼好測試、好擴展。
四、分佈式系統與性能
- ACID
這是數據庫事務的四個特性,原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
在金融交易這種對強一致性要求特別高的場景裏,就特別適用,它和BASE是不同的權衡方向。 - CAP定理
在分佈式系統裏,一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三個東西,沒辦法同時都滿足,最多就只能滿足其中兩個。
像金融交易系統,就得優先保證一致性和分區容錯性,也就是CP;社交媒體系統呢,就得優先保證可用性和分區容錯性,也就是AP。 - BASE理論
這理論是CAP定理的補充,它提出“基本可用,最終一致”,就是犧牲點強一致性,來換取可用性。它包括基本可用(就是系統出故障了,還能提供降級服務)、軟狀態(就是允許有中間狀態)、最終一致(就是系統最後肯定能達到一致狀態)。
在電商系統、緩存系統、消息隊列這些分佈式系統裏,就特別適用。 - 阿姆達爾定律 (Amdahl's Law)
這定律説的是,並行系統的性能提升,會受到串行部分比例的限制。它的公式是:加速比 = 1 / (串行比例 + (並行比例 / 處理器數量)) 。
在性能優化的時候,我們就得優先優化系統的串行瓶頸,像數據庫鎖、單線程處理這些,別盲目地去增加節點。 - 古斯塔夫森定律 (Gustafson's Law)
這定律説的是,隨着問題規模越來越大,並行部分的比例也會增加,系統的加速比就能接近處理器數量。
在大數據處理這種規模可以擴展的場景裏,就特別適用,通過增加節點就能線性提升性能。
五、組織與架構的關係
- 康威定律 (Conway's Law)
這定律説的是,系統架構能反映出組織的溝通結構,也就是“產品的結構等於組織的結構”。
比如在微服務拆分的時候,需要考慮團隊的結構是否是符合拆分後的服務邊界的。比如説如果是按業務線來劃分團隊的話,那就要對應着業務域來進行拆分服務,這樣能避免跨團隊頻繁溝通。 - 逆康威定律 (Inverse Conway's Law)
這定律説的是,可以通過設計系統架構,來影響組織的溝通結構和方式。比如説通過引入API網關,強制服務之間要通過接口的方式來進行通信。
在那種需要打破部門牆、促進協作的組織裏面,就特別適用,這樣就可以通過架構約束來引導組織變革。
六、可靠性與運維
- MTBF/MTTR
MTBF是Mean Time Between Failures的首字母縮寫,説的是系統平均出現故障時的間隔時間,能衡量系統靠不靠譜。MTTR是Mean Time To Recovery的首字母縮寫,説的是系統出現故障後平均需要的恢復時間,能衡量系統好不好維護。
在架構設計的時候,我可以通過冗餘、自動恢復這些機制,把MTBF提高;通過監控、灰度發佈這些辦法,把MTTR降低。 - 故障注入 (Chaos Engineering)
這個方法的核心就是主動的去模擬各種各樣的故障,像服務器宕機、網絡延遲、上游接口超時、中間件崩潰等這些情況,從而來驗證系統的容錯能力是否達到要求。
在高可用系統裏,像電商大促、金融核心系統這些,就特別適用這樣的方式,通過混沌工程來測試能發現潛在的弱點。
最後總結
架構設計原則、方法、模式這些內容其實還蠻多的,就像是我們蓋房子的時候的工具和圖紙。在不同的場景下,就得選不同的工具和圖紙。在實際的開發中,我們得根據項目的實際情況,靈活的運用這些原則和方法,才能設計出既靠譜又好維護的架構。而且架構設計也不是一成不變的,得隨着業務的發展和技術的進步,不斷調整和優化。只有這樣,我們的系統才能在複雜多變的環境裏,穩穩當當地運行下去,祝大家永遠都不會出Bug!
互動話題:大家在實際項目中,是如何運用架構設計原則和方法的?有哪些經驗可以分享?
關於作者
Kenyon,資深軟件架構師,15年的軟件開發和技術管理經驗,從程序員做到企業技術高管。多年企業數字化轉型和軟件架構設計經驗,善於幫助企業構建高質量、可維護的軟件系統,目前專注技術管理、架構設計、AI技術應用和落地;全網統一名稱"六邊形架構",歡迎關注交流。
原創不易,轉載請聯繫授權,如果覺得有幫助,請點贊、收藏、轉發三連支持!