我們在剛開始架構設計時手足無措,但是隨著我們完成一個又一個的系統架構設計以後,發現架構設計是有章法可循的,只要我們學習這些章法和套路,並且在工作過程中不斷的積累與沉澱,就會行成一個完整的架構設計方法論,面對新的大型系統架構設計,也會一步一步有節奏進行,最終完成整體的架構設計 ...
設計一個系統的過程,就是建造一座大廈的過程,架構設計的質量直接決定了大廈的質量。
在我們進行系統的架構設計時,總是會遇到一系列的問題,比如一個大型系統的架構應該如何起步,從哪裡開始設計?系統是否應該劃分成多個模塊,應該怎麼劃分模塊才更加的合理?亦或是覺得產品提出的需求非常不合理,完全影響我們正常的架構設計!對於非功能性的需求,我們是否可以得過且過,不去重視?
這些問題,讓我們在剛開始架構設計時手足無措,但是隨著我們完成一個又一個的系統架構設計以後,發現架構設計是有章法可循的,只要我們學習這些章法和套路,並且在工作過程中不斷的積累與沉澱,就會行成一個完整的架構設計方法論,面對新的大型系統架構設計,也會一步一步有節奏進行,最終完成整體的架構設計。
架構設計的原則
架構設計需要遵循一些原則:
1、架構設計需要方法體系
架構設計並不是一個”單一的方法“,直接拿來進行架構設計,而是多個各具特色的方法,組成的“方法體系”,並且這個體系隨著新技術的發展還會不斷進化。
2、架構設計是質疑驅動
架構設計是質疑驅動的過程,在”需求驅動“的基礎上,我們需要不斷的質疑我們架構設計的中間成果,進一步通過“質疑”,引入更多的“質量屬性”及更多“功能場景”。
3、多階段下的多視圖
架構設計,是多階段還是多視圖?架構設計首先是“多階段的”,我們將架構設計劃分成多個階段,在每個階段中才會考慮”視圖“這個維度。
架構設計的三個階段
階段一、 預備階段
預備階段的目標:全面理解需求,把握需求特點,確定架構設計驅動力。
在預備階段,我們需要全面的梳理與理解需求,不放過任何一個需求細節。同時分析需求產生的各項質量屬性與系統約束,同時兼顧這些約束進行架構設計,才能不遺漏重大的架構屬性。
階段二、 概念架構
概念架構,必須考慮包括功能,質量,約束在內的所有方面的需求。
階段三、 細化架構
在細化架構階段,我們從五個不同的角度出發,設計五個視圖,完成整個系統全方位的設計。
架構設計的一個貫穿環節
對非功能需求的考慮:非功能需求無法一蹴而就,因為在設計的過程當中,會有新的需求不斷的被髮現,即使設計完成,在開發階段,都會有影響非功能需求的約束出現,所以在整個階段,都應該註意非功能需求。
預備架構階段分析
預備架構的最重要的目標,是建立需求大局觀,把握需求特點,確定架構設計驅動力。通過對需求的詳細分析,有一個巨集觀的需求感知,同時還要兼顧系統的質量要求和約束對系統設計造成的制約條件。
需求結構化
需求是有結構的,而不是零散的需求點,只有將分析後的需求結構化,才能巨集觀的感知整個需求。可以藉助ADMEMS二維矩陣,將架構影響因素,梳理脈絡。
例如以下矩陣分析,將需求劃分為多個維度,橫向上從”廣義功能“,”質量“,”約束“三個方面分析,廣義功能是指需求需要滿足的基本功能,及產品或業務人員的直接要求。質量維度則是系統設計時需要考慮的高併發,高可用,可拓展等技術設計維護,保證系統在滿足基本需求的同時,同時對後續系統進化發展以及極端場景(例如:用戶量激增,秒殺)等的滿足。約束則是系統設計時的一些制約,例如上線日期,上線環境,開發人員技能水平等。縱向上劃分為”業務級需求“,”用戶級需求“,”開發級需求“三個維護,”業務級需求“是指產品或業務人員提出的基本要求,”用戶級需求“則是從系統的使用用戶角度出發,發現的例如用戶電腦操作水平,用戶使用習慣等潛在需求,而”開發級需求“,則是從研發人員角度出發,發現的例如可拓展,可測試,技術環境等不同維度的需求。
通過將需求結構化,我們可以全面的分析整體的需求,對需求進行整體的理解,同時也可以從不同的角度發現系統制約條件,在系統設計的最開始階段就著手設計,防止遺漏重大約束導致架構設計失敗。
分析約束影響
約束分析的幾個方面:
1、 來自產品或運營人員的約束性需求
系統的非功能需求,例如:上線時間,預算,工期要求等
業務領域相關的限制,例如業務規則或業務限制,相關法律,專利等。
2、 來自用戶的約束性需求
系統的用戶,同樣會產生約束性需求,比如用戶的電腦水平,年齡段,使用偏好,國家等。
例如用戶電腦水平整體較弱的話,在開發交互方式時就不應太過複雜,同時要兼顧系統的魯棒性,防止系統被用戶搞掛。
用戶使用產品時的外部環境同樣可能產生約束條件,比如訪問環境是內網或是外網,則決定了系統提供訪問鏈接不同的網路許可權。訪問環境信號強度若,則系統的性能要求則更高。
3、 來自開發或運維人員的約束性需求
開發團隊的技術水平,磨合程度,同樣制約著系統的開發,如果開發人員均是高級研發人員且對當前技術棧有深入的瞭解,則開發進度就會更快,如果是新團隊,且需要對技術棧進行學習才可以介入開發,則在工期或系統風險層面需要額外考慮。
4、 業界當前技術環境
當前技術環境中間件的成熟程度,編程語言及流行度,優缺點等,都會對架構設計產生約束條件。
約束的分類:
1、 直接約束
例如:系統運行於linux平臺。
2、 轉換為功能需求的約束
對於這種約束,可以直接轉換為功能需求
例如:供應商擁有自己的一套城市信息表 -> 引出的功能需求:需要進行城市轉換
例如:供應商伺服器性能差,tps最大10 -> 引出的功能需求:需要進行限流請求
3、 轉換為質量屬性需求的約束
例如:系統使用者電腦水平不高
轉換為質量屬性:易用性(否則不會用),魯棒性(系統被搞癱)
確定關鍵質量
系統的關鍵質量是需要進行取捨的,需要確認業務人員更註重那方面或在滿足需求的基礎上,確定哪些是必須的,哪些是可以適當忽略的。
我們需要首先確定架構重點支持哪些質量屬性,然後對於相互矛盾的質量屬性,進行權衡折中。例如當滿足性能這個質量屬性時,同時就會因為引入新的方案或組件,導致可維護性,可測試性降低;提高可拓展性時,就會對系統的性能和安全性產生影響等等,我們需要做的,就是在各個關鍵質量中進行取捨。
確定關鍵功能
確定關鍵功能的4個方面
1、 核心功能
2、 必做功能
3、 高風險功能
4、 獨特功能
其他常見系統不存在的功能
註意衍生需求:
從需求轉入設計時,因方案制定過程的複雜,會產生大量的衍生需求,衍生需求是原始需求的數倍。
舉例:
原始需求:定時拉取供應商數據。
衍生需求:
1、 由於供應商數量較多,需要引入分散式定時任務,集群併發拉取
2、 由於供應商數據量大,需要分庫分表設計
3、需要快速搜索,引入存儲引擎組件等等
這些衍生需求我們必須要考慮,雖然業務需求沒有體現,但缺失架構設計的關鍵影響因素。
架構驅動力對比:
業務需求驅動架構:
重大需求驅動架構:
由此可以看出,通過重大需求驅動的架構,更能考慮到更關鍵的部分,設計的架構更能滿足需求的要求,架構設計成功的概率會更高。
概念架構階段分析
概念架構階段,對系統進行適當的分解,而不陷入細節
概念架構的過程是,先根據關鍵功能進行初步設計,然後對設計的系統進行高層分割,接下來考慮非功能性需求(關鍵質量和約束),然後修改自己的初步設計,迴圈往複,在不斷的質疑和優化過程中,完善架構設計。
初步設計
初步設計的目標是發現職責,無需展開細節設計。基於關鍵功能,進行初步設計,基於主流程,關鍵流程,黃金流程等進行流轉圖設計,從而發現職責。
高層分割
切分複雜系統,為多個二級系統。或者直接切分為具體子系統。
高層分割的兩種方式:
1、 系統切分
切分的考慮點,包括系統功能、部署環境、語言、系統規模等
例如一個大型系統,切分為訂單,商品,供應鏈等系統。
2、 系統內切分
根據系統的職責、調用關係、通用性等,進行系統內部切分。
最常見的就是分層,例如一個系統,切分為網關層,服務層,搜索模塊,man端等。
分層的角度
1、 邏輯分層
邏輯分層重視職責的劃分,職責直接常常是上層使用下層的關係,上層和下層,可以是分佈在不同的機器,也可以分佈在同一臺機器。
2、 物理分層
分佈在不同機器上的軟體單元。
3、 通用性分層
通用性不同的,劃分為不同的層,一般通用性越大,所處的層次越靠下。
考慮非功能需求
具體方法是:採用目標-場景-決策表,見下圖:
架構設計是質疑驅動的,例如,質疑係統的可用性,考慮系統可能宕機,則引入集群部署設計,考慮下游介面可能超時或出現異常,則引入介面降級的設計等。
考慮場景的5個要素
1、 影響來源,來自系統內部還是系統外部
2、 如何影響的
3、 受影響的對象
4、 有什麼問題或有什麼價值
5、 所處的環境為何
對場景的權衡因素:
價值,代價,開發難度,出現幾率。對於某些場景,經過全面的權衡和思考,可以不支持,並不是所有的場景都要支持,否則可能存在過度設計。
細化架構階段分析
邏輯視圖
邏輯視圖是對系統的不同部分職責的劃分,根據職責不同,可以將系統進行細粒度的拆分,劃分為多個子系統。
分層的細化
根據系統設計的需要,可以將系統的分層進行細化,例如展示層 -> 業務層 -> 數據層 可以細化為:展示層 -> 控制層 -> 介面層 -> 介面實現層 -> 數據層。
分區的引入
分區的概念是業務流程相關的,分區的依據是:職責,比如結算流程可以作為一個分區,下單流程可以作為一個分區。將系統劃分為多個分區,一方面可以支持並行開發,另一方面也將系統劃分為多個子域,有利於業務概念和業務流程的收斂。
機制的提取
機制是指系統可以抽象的公共部分,例如公共工具,公共組件,公共流程等,提取這些公共部分,對於架構設計是至關重要的。
劃分子系統的原則:
1、 職責不同的單元,劃分為不同的子系統
2、 通用性不同的單元,劃分為不同的子系統
3、 需要不同開發技能的單元,劃分為不同的子系統兼顧工作量,進一步切分太大的系統
開發視圖
開發架構視圖的任務,是將“邏輯職責”映射為“程式單元”,例如:要自主編寫的“源程式”,可重用的庫,框架等;同時進行開發技術選型,例如:開發語言,開發工具等,然後也需要確立程式單元間的關係,project劃分,目錄結構,編譯依賴關係等。
運行視圖
運行架構設計的工作內容,是確定引入哪些控制流:進程,線程等;確定每條控制流的任務,同時還要處理相關問題,例如控制流的創建,銷毀,通信機制等,控制流之間的同步關係,是否有資源爭用,是否需要加鎖等也需要考慮。
物理視圖
物理架構設計的3項任務
1. 硬體的選擇與物理拓撲
2. 軟體到硬體的映射關係
3. 方案的優化
思維要點:“開銷”和“爭用”是核心,應避免爭用,降低開銷。
數據視圖
數據視圖是系統的數據存儲設計,根據對系統的分析,確定一種或多種數據策略,常見的數據分佈策略如下6種:
1、獨立的Schema
不同系統應用,使用不同的數據schema,數據完全獨立,一般界限清晰的不同系統可以採用這種方式。
2、集中
不同的系統應用,使用同一個資料庫,一般具有關聯屬性的應用可以採用這種方式,比如一個系統分為服務端和管理端,但都屬於一個系統,則可以使用同一個資料庫。
3、分區
水平分區
水平分區即我們常見的分表方案,當一個schema無法滿足我們的數據量要求時,可以劃分為多個分區,每個分區存儲一部分數據。
垂直分區
垂直分區是分區策略的另外一個維度,當我們單庫無法承載巨大的數據量時,也可以根據數據的類別,進行垂直分區。
4、複製
多個資料庫保存相同的數據,根據制定的更新策略保證不同庫之間的數據同步,我們常用的讀寫庫分離,即為此方案,主庫提供寫能力,從庫提供讀能力,其中從庫的數據是根據主庫數據同步而來。
5、子集
根據一些特殊的場景要求,需要保存原數據的部分數據,例如application1保存全量訂單,application2只需要部分出票成功的訂單,進行後續分析操作,則可以使用子集的策略進行數據視圖設計。
6、重組
通過多個不同的application作為數據來源,異構至其他application,用於數據的分析或後續流程使用。
總結
架構設計的三個階段:預備架構階段;概念架構階段;細化架構階段
架構設計的四個要素:需求結構化;分析約束的影響;確定關鍵質量;確定關鍵功能
概念架構的三個步驟:基於關鍵功能初步設計;系統高層分割;分析非功能需求
細化架構的五個視圖:邏輯視圖;開發視圖;運行視圖;物理視圖;數據視圖
一個貫穿環節:非功能需求的考慮
參考資料
1.《一線架構設計指南》
作者:京東零售 馮曉濤
來源:京東雲開發者社區 轉載請註明來源