架構師必須知道的架構設計原則

無論你是新手程序員、職場老司機,仍是資深架構師,這篇文章對你來講應該都有裨益。雖然還是假期,但也建議你多花點時間讀一讀這些真言。
寫在前面
若是一個技術已經存在 2 年,好比如今很火的前端技術 react 和 vue 等,那麼我能預估這個技術大體還有 2 年的生命期,再久就不肯定了;若是一個架構或設計原則已經存在 15 年,例如單一職責和依賴倒置原則,我能夠預期它還有 15 年甚至更久的生命期。原則是比具體技術更抽象,更接近事物本質,也更經得起時間考驗的東西。這些原則沉澱在架構師的腦海中,最終內化成他的 mindset,以潛意識方式影響和指導他的架構和設計工做。
一晃我在軟件研發行業工做十多個年頭了,前面大部分時間作架構設計和開發,如今轉型作研發管理。隨着時間的推移,不少技戰術細節性的東西 (工具,框架,編程語言) 在我腦海中漸漸模糊,可是一些平時學習積累起來,而且在實踐中加深體會的軟件架構設計和組織原則,這些原則性的東西卻絲毫沒有被時間沖淡,反而越發清新。如今即便我不在一線開發,但這些沉澱下來的原則仍然潛移默化地影響個人平常管理和部分架構設計指導工做。我想有必要總結一下那些業界知名,給我留下深入印象的軟件架構設計和組織原則,和你們一塊兒分享。
軟件設計原則
GRASP 通用職責分配軟件模式
來自 Craig Larman 的軟件設計書《UML 和模式應用》[附錄 1],Larman 在書中提出軟件設計的關鍵任務是職責分配,並提煉總結出 9 種 (5 種核心 +4 種擴展) 軟件職責分配模式,這些模式是比 GoF 設計模式更抽象的元模式。
1. 信息專家 (Information Expert)
爲對象分配職責的通用原則 – 把職責分配給擁有足夠信息能夠履行職責的專家
2. 建立者 (Creator)
將建立 A 的職責賦給 B,若是至少下面一種狀況爲真:
* B「包含」或者聚合 A * B 記錄 A 的實例 * B 密切地使用 A * B 擁有 A 的初始化數據
3. 低耦合 (Low Coupling)
賦予職責使得對象間的耦合度儘量低,最小化對象間的依賴和變動影響,最大化重用。
4. 高內聚 (High Cohesion)
賦予職責使得每一個對象的職責儘量保持聚焦和單一,易於管理和理解。
5. 控制器 (Controller)
把職責賦予系統、設備或者子系統的表示類 (門面控制器),或者某個用例的表示類 (用例控制器),讓控制器接收事件並協調整個系統的運做。
6. 多態 (Polymorphism)
將職責分配給多個具備同名方法的多態子類,運行時根據須要動態切換子類,讓系統行爲變得可插拔。
7. 純虛構 (Pure Fabrication)
針對真實問題域中不存在,可是設計建模中有用的概念,設計虛構類並賦予職責。
8. 間接 (Indirection)
在兩個或者多個對象間有交互的狀況下,爲避免直接耦合,提升重用性,建立中間類並賦予職責,對象的交互交由中間類協調。
9. 受保護的變化 (Protected Variation)
簡單講就是封裝變化。識別系統中可能的不穩定或者變化,在不穩定組件上建立穩定的抽象接口,將可能的變化封裝在接口以後,使得系統內部的不穩定或者變化不會對系統的其它部分產生不良影響。
SOLID 面向對象設計原則
S.O.L.I.D 是面向對象設計和編程 (OOD&OOP) 中幾個重要原則的首字母縮寫,受 Robert Martin 推崇。
1. 單一職責原則 (The Single Responsibility Principle)
修改某個類的理由應該只有一個,若是超過一個,說明類承擔不止一個職責,要視狀況拆分。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/E164B18101464A4F969C9629937F52A2/2480)
2. 開放封閉原則 (The Open Closed Principle)
軟件實體應該對擴展開放,對修改封閉。通常不要直接修改類庫源碼(即便你有源代碼),經過繼承等方式擴展。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/14CA4061A37744DB864BB0AE064E13D0/2483)
3. 里氏替代原則 (The Liskov Substitution Principle)
當一個子類的實例可以被替換成任何超類的實例時,它們之間纔是真正的 is-a 關係。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/46A909D248D042758244123824E4633F/2485)
4. 依賴倒置原則 (The Dependency Inversion Principle)
高層模塊不該該依賴於底層模塊,兩者都應該依賴於抽象。換句話說,依賴於抽象,不要依賴於具體實現。比方說,你不會把電器電源線焊死在室內電源接口處,而是用標準的插頭插在標準的插座 (抽象) 上。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/87E1DE11C3C942E4B5857B13ACE993AF/2481)
5. 接口分離原則 (The Interface Segregation Principle)
不要強迫用戶去依賴它們不使用的接口。換句話說,使用多個專門的接口比使用單一的大而全接口要好。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/1E41A4692C4A429C89406259647F2613/2482)
個人解讀
1. 我職業早年主要關注軟件設計和編程,因此花蠻多時間學習和消化 GRASP 和 SOLID 設計原則。這些原則對我影響很深,尤爲是單一職責,信息專家,關注分離,依賴倒置 / 封裝變化,分而治之等核心原則,如今平常研發中我時經常使用這些原則指導新手工程師。 2. 高內聚 + 低耦合,就像道中的一陰一陽,是全部其它 OO 設計原則的原則 (元原則),其它設計原則都是在這兩個基礎上泛化衍生出來的。 3. 上述原則雖然是針對 OO 設計和編程提出,可是對於大規模系統架構仍然適用。好比,微服務架構就體現了: 1. 做爲架構師或者設計師,有兩個設計能力是須要重點培養的,也是最難和最能體現架構設計水平的:
分佈式系統架構設計原則和理論
AKF 架構原則
這 15 個架構原則來自《架構即將來 (The Art of Scalability)》[附錄 2] 一書,做者馬丁 L. 阿伯特和邁克爾 T. 費舍爾分別是 eBay 和 PayPal 的前 CTO,他們經歷過 eBay 和 PayPal 大規模分佈式電商平臺的架構演進,在一線實戰經驗的基礎上總結並提煉出 15 條架構原則:
1.N + 1 設計
永遠不要少於兩個,一般爲三個。比方說無狀態的 Web/API 通常部署至少>=2 個。
2. 回滾設計
確保系統能夠回滾到之前發佈過的任何版本。能夠經過發佈系統保留歷史版本,或者代碼中引入動態開關切換機制 (Feature Switch)。
3. 禁用設計
可以關閉任何發佈的功能。新功能隱藏在動態開關機制 (Feature Switch) 後面,能夠按需一鍵打開,如發現問題隨時關閉禁用。
4. 監控設計
在設計階段就必須考慮監控,而不是在實施完畢以後補充。例如在需求階段就要考慮關鍵指標監控項,這就是度量驅動開發 (Metrics Driven Development) 的理念。
5. 設計多活數據中心
不要被一個數據中心的解決方案把本身限制住。固然也要考慮成本和公司規模發展階段。
6. 使用成熟的技術
只用確實好用的技術。商業組織畢竟不是研究機構,技術要落地實用,成熟的技術通常坑都被踩平了,新技術在徹底成熟前通常須要踩坑躺坑。
7. 異步設計
能異步儘可能用異步,只有當絕對必要或者沒法異步時,才使用同步調用。
8. 無狀態系統
儘量無狀態,只有當業務確實須要,才使用狀態。無狀態系統易於擴展,有狀態系統不易擴展且狀態複雜時更易出錯。
9. 水平擴展而非垂直升級
永遠不要依賴更大、更快的系統。通常公司成長到必定階段廣泛經歷過買更大、更快系統的階段,即便淘寶當年也買小型機扛流量,後來扛不住才體會這樣作不 scalable,因此纔有後來的去 IOE 行動。
10. 設計時至少要有兩步前瞻性
在擴展性問題發生前考慮好下一步的行動計劃。架構師的價值就體如今這裏,架構設計對於流量的增加要有提早量。
11. 非核心則購買
若是不是你最擅長,也提供不了差別化的競爭優點則直接購買。避免 Not Invented Here 症狀,避免凡事都要重造輪子,畢竟達成業務目標纔是重點。
12. 使用商品化硬件
在大多數狀況下,便宜的就是最好的。這點和第 9 點是一致的,經過商品化硬件水平擴展,而不是買更大、更快的系統。
13. 小構建、小發布和快試錯
所有研發要小構建,不斷迭代,讓系統不斷成長。這個和微服務理念一致。
14. 隔離故障
實現故障隔離設計,經過斷路保護避免故障傳播和交叉影響。經過艙壁泳道等機制隔離失敗單元 (Failure Unit),一個單元的失敗不至影響其它單元的正常工做。
15. 自動化
設計和構建自動化的過程。若是機器能夠作,就不要依賴於人。自動化是 DevOps 的基礎。
個人解讀
1. 這 15 條架構原則基本上是 eBay 在發展,經歷過流量數量級增加衝擊過程當中,經過不斷踩坑踩出來的,是乾貨中的乾貨。消化吸取這 15 條原則,基本可保系統架構不會有原則性問題。 2. 這 15 條原則一樣適用於如今的微服務架構。eBay 發展較早,它內部其實很早 (差很少 2010 年前) 就已造成完善的微服務生態,只是沒有提出微服務這個概念。 3. 這 15 條原則可根據 TTM(Time To Market),可用性 / 可擴展性 / 質量,成本 / 效率分佈在三個環內,以下圖所示。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/E5776128CB4543A78DE92EC7CA94EBBB/2489)
12 要素應用
Heroku[附錄 3] 是國外知名的雲應用平臺。基於上百萬應用的託管和運營經驗,創始人 Adam Wiggins 提出了 12 要素應用宣言 [附錄 4]。簡單講,知足這 12 個要素的應用是比較容易雲化並居住在 Heroku 平臺上的。
1. 基準代碼
一份基準代碼,多份部署。若是用鏡像部署方式,則一個鏡像能夠部署到多個環境 (測試,預發,生產),而不是給每一個環境製做一個不一樣鏡像。
2. 依賴
顯式聲明依賴。若是用鏡像部署,則通常依賴被直接打在鏡像中,或者聲明在 docker file 中。
3. 配置
在環境中存儲配置。在 Heroku 或者相似的 PaaS 平臺上,配置通常是推薦注入到環境變量中的。如今採用集中式配置中心也是一種流行方式。
4. 後端服務
把後端服務 (例如緩存,數據庫,MQ 等) 看成附加資源,相關配置和鏈接字符串經過環境變量注入,或者採用配置中心。
5. 構建、發佈和運行
嚴格分離構建和運行。若是使用鏡像部署,則構建、發佈 / 運行是經過鏡像這種中間格式嚴格分離的。
6. 進程
一個或者多個無狀態的進程運行應用。容器運行時至關於進程,適用於無狀態 Web/API。
7. 端口綁定
經過端口綁定提供服務。容器也是經過端口綁定對外提供服務。
8. 併發
經過進程模型進行擴展。容器運行時至關於進程,經過起多個容器能夠任意擴展併發數量。
9. 易處理
快速啓動和優雅終止可最大化健壯性。docker 容器支持秒級啓動和關閉。
10. 開發環境和線上環境等價
儘量保持開發、測試、預發和線上環境相同。容器能夠保證容器內運行時環境的一致性,還須要保證不一樣環境的一致性,例如不一樣環境內的操做系統,負載均衡,服務發現,後臺服務,監控告警等要儘量一致。
11. 日誌
把日誌看成數據流。Heroku 不支持本地文件,因此必須以流方式把日誌輸送到後臺日誌服務。除了日誌之外還要補充考慮 metrics 流的採集和輸送。
12. 管理進程
後臺管理任務看成一次性的進程。其實至關於在 Heroku 上以獨立進程方式運行任務 Job。
個人解讀
1. 12 要素應用也是當前雲原生應用 (Cloud Native App) 的參考標準,我把這 12 要素也稱爲雲應用遷移原則。知足這 12 個要素的應用,能夠比較順利遷移到各類雲平臺 (Kubernetes, Marathon, Cloud Foundry 等) 上。 2. 對於面臨企業遺留應用改造和雲化遷移的架構師,能夠重點參考這 12 條遷移原則。 3. Docker 容器技術能夠認爲是爲雲遷移量身定製的技術。容器化是後續雲遷移的捷徑,因此遺留應用改造能夠先想辦法作到容器化。
CAP 定理
2000 年 7 月,加州大學伯克利分校的 Eric Brewer 教授在 ACM PODC 會議上提出 CAP 猜測。2 年後,麻省理工學院的 Seth Gilbert 和 Nancy Lynch 從理論上證實了 CAP。以後,CAP 理論正式成爲分佈式計算領域的公認定理。
CAP 認爲:一個分佈式系統最多同時知足一致性 (Consistency),可用性 (Availability) 和分區容忍性 (Partition Tolerance) 這三項中的兩項。
1.一致性 (Consistency)
一致性指「all nodes see the same data at the same time」,即更新操做成功,全部節點在同一時間的數據徹底一致。
2.可用性 (Availability)
可用性指「Reads and writes always succeed」,即服務一直可用,並且響應時間正常。
3.分區容忍性 (Partition tolerance)
分區容忍性指「the system continue to operate despite arbitrary message loss or failure of part of the system.」,即分佈式系統在遇到某節點或網絡分區故障時,仍然可以對外提供知足一致性和可用性的服務。
![](images/replace-img.png)
BASE 理論
eBay 架構師 Dan Pritchett 基於對大規模分佈式系統的實踐總結,在 ACM 上發表文章提出了 BASE 理論,BASE 理論是對於 CAP 理論的延伸,核心思想是即便沒法作到強一致性 (Strong Consistency,CAP 中的一致性指強一致性),可是能夠採用適當的方式達到最終一致性 (Eventual Consistency)。
BASE 指基本可用 (Basically Available)、軟狀態 (Soft State) 和最終一致性 (Eventual Consistency)。
1.基本可用 (Basically Available)
基本可用是指分佈式系統在出現故障時,容許損失部分可用性,即保證核心可用。好比服務降級。
2.軟狀態 (Soft State)
軟狀態是指容許系統存在中間狀態,而該中間狀態不會影響系統的總體可用性。分佈式存儲中通常一份數據至少存三個副本,容許不一樣節點間副本同步的延遲就是軟狀態的體現。
3.最終一致性 (Eventual Consistency)
最終一致性是指系統中的全部數據副本通過一段時間後,最終可以達成一致狀態。弱一致性和強一致性相反,最終一致性是弱一致性的一種特殊狀況。
![](images/replace-img.png)
個人解讀
1. CAP 和 BASE 理論能夠摳得很深,背後甚至有很複雜的數學證實。我理解得相對簡單淺顯:性能、高可用、不丟數據和數據一致性對分佈式系統來講通常是強需求,隨着流量的增加,複製和分區在所不免: 1. 選擇使用分佈式產品時,好比 NoSQL 數據庫,你須要瞭解它在 CAP 環中所在的位置,確保它知足你的場景須要。
組織和系統改進原則
康威法則
Melvin Conway 在 1967 年提出所謂康威法則 [附錄 5],指出組織架構和系統架構之間有一種隱含的映射關係:
Organization which design system […] are constrained to produce designs which are copies of the communication structures of these organization. 設計系統的組織其產生的設計等價於組織間的溝通結構。
![](images/replace-img.png)
康威法則也能夠倒過來闡述:
Conway’s law reversed:You won’t be able to successfully establish an efficient organization structure that is not supported by your system design(architecture)。 若是系統架構不支持,你沒法創建一個高效的組織;一樣,若是你的組織架構不支持,你也沒法創建一個高效的系統架構。
![](images/replace-img.png)
系統改進三原則
IT 運維管理暢銷書《鳳凰項目》[附錄 8] 的做者 Gene Kim 在調研了衆多高效能 IT 組織後總結出支撐 DevOps 運做的三個原理 (The Three Ways: The Principles Underpinning DevOps)[附錄 9],我認爲也是系統改進提高的通常性原理 [附錄 7],見下圖:
![](images/replace-img.png)
原理一:系統思考 (System Thinking)
開發驅動的組織,其能力不是製做軟件,而是持續的交付客戶價值。價值從業務需求開始,通過研發測試,到部署運維,依次流動,並最終以服務形式交付到客戶手中。整個價值鏈流速並不依賴單個部分 (團隊或我的) 的傑出工做,而是受整個價值鏈最薄弱環節 (瓶頸) 的限制。因此局部優化一般無效,反而招致全局受損。
Gene Kim 特別指出:Any improvements made anywhere besides the bottleneck are an illusion. 在瓶頸以外的任何優化提高都只是幻象。
原理二:強化反饋環 (Amplify Feedback Loops)
過程改進經常經過增強反饋環來達成。原理二強調企業和客戶之間、組織團隊間、流程上和系統內的反饋環。沒有測量就沒有提高,反饋要以測量數據爲準,經過反饋數據優化改進系統。
原理三:持續試驗和學習的文化 (Culture of Continual Experimentation And Learning)
在企業管理文化層面強調敢於試錯和持續試驗、學習和改進的文化。
個人解讀
1. 康威法則給咱們的啓示:系統架構和組織架構之間有隱含的映射關係,你不能單方面改變一方的結構,調整時必須兩邊聯動。系統架構若是是耦合的,就很難組織分散式的團隊結構,兩邊映射不起來,團隊之間容易摩擦致使生產率降低。因此通常先按業務邊界對單塊應用進行解耦拆分,同時作相應的團隊拆分,使兩邊能夠映射,每一個團隊能夠獨立開發、測試和部署各自的微服務,進而提高生產率。這就是近年流行的微服務架構背後的組織原則。詳見我以前發表的文章《企業的組織架構是如何影響技術架構的》[附錄 6]。 2. 系統思考要求咱們增強團隊合做,培養流式思惟和瓶頸約束思惟,找出瓶頸並針對性地優化。在研發型組織中,常見的系統瓶頸如運維機器資源提供 (Provisioning) 緩慢,發佈流程繁瑣容易出錯,開發 / 測試/UAT 環境缺失或不完善,遺留系統耦合歷史負擔重,基礎研發平臺薄弱等等。這些瓶頸點特別須要關注優化。 3. 反饋原理要求咱們關注基於數據的反饋,技術上的手段包括大數據分析和系統各個層次的測量監控。沒有測量就沒有反饋,沒有反饋就沒有提高。 4. 在管理文化層面:
寫在最後
上述原則是架構師必須深刻理解和掌握的,可是不能盲從,實際工做中要根據業務、時間、資源和團隊狀況隨機應變。原則有時甚至能夠被違反,固然這樣作必定有成本,架構師要意識這一點,並適時變通補償。
上述原則僅是我我的視角總結,有些理解不免偏頗。若是你認爲我忽略了哪些重要的原則,或理解有誤,請記得線下和我交流!
參考
1. UML 和模式應用 (原書第 3 版)
https://www.amazon.cn/UML%E5%92%8C%E6%A8%A1%E5%BC%8F%E5%BA%94%E7%94%A8-%E6%8B%89%E6%9B%BC/dp/B00116WMSU
1. 架構即將來:現代企業可擴展的 Web 架構、流程和組織 (原書第 2 版)
https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B01DXW29IM
1. Heroku 雲應用平臺
https://www.heroku.com/
1. The Twelve-Factor App
https://12factor.net/zh_cn/
1. 康威法則
https://en.wikipedia.org/wiki/Conway%27s_law
1. 企業的組織架構是如何影響技術架構的
http://www.infoq.com/cn/articles/organization-arch-influence-technology-arch
1. 痛定思痛,談成長型公司應該如何突破方輪子困局!
http://www.sohu.com/a/123304174_467759
1. 鳳凰項目:一個 IT 運維的傳奇故事
https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B016VW1I6U
1. The Three Ways: The Principles Underpinning DevOps
https://itrevolution.com/the-three-ways-principles-underpinning-devops/
做者介紹
楊波 ,拍拍貸基礎框架研發總監。具備超過 10 年的互聯網分佈式系統研發和架構經驗,曾前後就任於:eBay 中國研發中心(eBay CDC),任資深研發工程師,參與億貝開放 API 平臺研發,攜程旅遊網(Ctrip),任技術研發總監,主導攜程大規模 SOA 體系建設,惟品會(VIPShop),任資深雲平臺架構師,負責容器 PaaS 平臺的調研和架構。
相關文章
相關標籤/搜索