設計一個系統的過程,就是建造一座大廈的過程,架構設計的質量直接決定了大廈的質量。
在我們進行系統的架構設計時,總是會遇到一系列的問題,比如一個大型系統的架構應該如何起步,從哪裡開始設計?系統是否應該劃分成多個模組,應該怎麼劃分模組才更加的合理?亦或是覺得產品提出的需求非常不合理,完全影響我們正常的架構設計!對於非功能性的需求,我們是否可以得過且過,不去重視?
這些問題,讓我們在剛開始架構設計時手足無措,但是隨著我們完成一個又一個的系統架構設計以後,發現架構設計是有章法可循的,只要我們學習這些章法和套路,並且在工作過程中不斷的積累與沉澱,就會行成一個完整的架構設計方法論,面對新的大型系統架構設計,也會一步一步有節奏進行,最終完成整體的架構設計。
架構設計需要遵循一些原則:
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.《一線架構設計指南》
作者:京東零售 馮曉濤
來源:京東雲開發者社群 轉載請註明來源