架構設計(7)—如何設計一個架構
願景已經確定架構願景和目標。
需求分析明確架構要解決當前什麼問題。
那接下來就是如何著手開始做架構設計。
一、如何開始設計一個架構:方式方法
架構不是像平常寫程式碼一樣,對就是對,錯就是錯,它並無對錯之分,是一個取捨的過程。當我們從0開始做架構的時候,的確是比較困難。雖然萬事開頭難,但是一個好的開始相當於成功了一半,會給我們接下去的工作打下結實的基礎。
我的經驗步驟是:業務->功能->技術實現->架構綜覽圖
1、業務架構:確定總體架構,核心流程, 是最上層的戰略架構.
包括業務規劃,業務模組、業務流程,對整個系統的業務進行拆分,對領域模型進行設計,把現實的業務轉化成抽象物件。
沒有最優的架構,只有最合適的架構,一切系統設計原則都要以解決業務問題為最終目標,脫離實際業務的技術情懷架構往往會給系統帶入大坑,任何不基於業務做異想天開的架構都是耍流氓。
所有問題的前提要搞清楚我們今天面臨的業務量有多大,增長走勢是什麼樣,而且解決高併發的過程,一定是一個循序漸進逐步的過程。 合理的架構能夠提前預見業務發展1~2年為宜。這樣可以付出較為合理的代價換來真正達到技術引領業務成長的效果。
2、應用架構:確定子系統的功能範圍和劃分解決方案:
應用作為獨立可部署的單元,為系統劃分了明確的邊界,深刻影響系統功能組織、程式碼開發、部署和運維等各方面. 應用架構定義系統有哪些應用、以及應用之間如何分工和合作。這裡所謂應用就是各個邏輯模組或者子系統。
應用架構圖關鍵有2點:
1、職責劃分: 明確應用(各個邏輯模組或者子系統)邊界
1)邏輯分層
2)子系統、模組定義。
3)關鍵類。
2、職責之間的協作:
1)介面協議:應用對外輸出的介面。
2)協作關係:應用之間的呼叫關係。
應用分層有兩種方式:
一種是水平分(橫向),按照功能處理順序劃分應用,比如把系統分為web前端/中間服務/後臺任務,這是面向業務深度的劃分。
另一種是垂直分(縱向),按照不同的業務型別劃分應用,比如進銷存系統可以劃分為三個獨立的應用,這是面向業務廣度的劃分。
應用的合反映應用之間如何協作,共同完成複雜的業務case,主要體現在應用之間的通訊機制和資料格式,通訊機制可以是同步呼叫/非同步訊息/共享DB訪問等,資料格式可以是文字/XML/JSON/二進位制等。
應用的分偏向於業務,反映業務架構,應用的合偏向於技術,影響技術架構。分降低了業務複雜度,系統更有序,合增加了技術複雜度,系統更無序。
應用架構的本質是通過系統拆分,平衡業務和技術複雜性,保證系統形散神不散。
分久必合,合久必分,結合當前的實際資源情況做出最終的決策,這是整個過程中最耗時的點,它決定著架構的複雜度和開發成本。方式上包括但不限於抽出可重用的功能、功能的組合、拆分粒度更細的功能提高可重用性等等。這一切的決策都要以“恰到好處”為宜。千萬不要盲目的跟從微服務之風!千萬不要盲目的跟從微服務之風!千萬不要盲目的跟從微服務之風!重要的事情說3遍。服務粒度越細,呼叫鏈路越複雜,帶來的開發成本是否適合團隊,是作為一個架構師需要著重考量的點。
系統採用什麼樣的應用架構,受業務複雜性影響,包括企業發展階段和業務特點;同時受技術複雜性影響,包括IT技術發展階段和內部技術人員水平。業務複雜性(包括業務量大)必然帶來技術複雜性,應用架構目標是解決業務複雜性的同時,避免技術太複雜,確保業務架構落地。
3、技術架構: 技術調研, 確定系統核心技術點
1、技術選型: 根據業務場景, 瞭解業內的玩法,能不能解決現有問題. 比如使用微服務構建,dubbo,spring cloud.
2、評估技術成本: 結合業內的玩法與自有技術體系的結合成本,評估使用成本,推廣成本.
例如要使用dubbo,評估現有開發人員能不能hold住, 重構成本有多大.
3、方案取捨: 技術方案有多種,瞭解每種方案優缺點, 讓大家參與討論.
4、確定系統核心技術方案:
技術架構最終是確定組成應用系統的實際執行元件(lvs,nginx,tomcat等),這些執行元件之間的關係,以及部署到硬體的策略。
技術架構還要考慮系統的非功能性特徵,對系統的高可用、高效能、擴充套件、安全、伸縮性、簡潔等做系統級的把握。
系統架構的設計要求架構師具備軟體和硬體的功能和效能的過硬知識,這也是架構設計工作中最為困難的工作。
4、資料架構:
資料架構指導資料庫的設計
5、架構總覽圖:
架構綜覽圖,
這樣能夠幫助站在一個更高的角度去考慮架構的演變問題。如果是針對現存專案重新做架構,那麼需要把現有專案架構梳理出來,作為我們上面思考過程中的一部分參考資訊。
6,詳細設計與實施
這個架構設計步驟即使就是套路,即方法論, 不論是大系統,還是單個應用系統, 都可以使用這個套路.
比如我們要設計一個微服務的訂單系統:
1、業務: 確定業務流程: 確定訂單關鍵功能點和流程
2、應用: 確定訂單頂層設計,系統模組,對外暴露哪些介面. 介面協議形式.
3、技術: 確定使用哪些技術點: mysql, mongo,是否考慮分表分庫. 使用哪些中介軟體.
4、資料: 如何設計表結構.
5、詳細設計:
二、技術選型: 指導原則
架構設計並沒有像程式語言那樣的語法約束,更多的時候是面多多種可能時的“選擇”:
例如:
- 選先進的技術還是團隊熟悉的技術?先進的出問題怎麼辦?熟悉的後續技術演化困難怎麼辦?
- 用Angular還是React,一個很強大一個更靈活
- MySQL還是MongoDB?
- 淘寶的電商架構咳喲簡單的照搬麼?
- 等等
但存在共性原則:合適原則、簡單原則、演化原則
1、合適原則:合適優於業界領先
優秀人才的技術情節導致各種以先進技術主導的創業失敗,原因有:
- 將軍難打無兵之仗(人數)
- 羅馬不是一天建成的(積累)
- 冰山下面才是關鍵(業務)
所以真正的優秀架構都是在企業當前人力、條件、業務等各種約束下設計出來的。BAT的架構師到小公司沒有了大公司的資源、平臺、積累和業務,只照搬大公司的做法和技術即會失敗!
2、簡單原則:簡單優於複雜。
軟體領域複雜度體現兩個方面:
1)、結構的複雜性
- 組成複雜系統的元件數量更多
- 同時這些元件之間的關係也更加複雜
- 元件增多整體出現鼓掌的概率增加,可用性下降
- 某個元件改動會影響關聯的所有元件
- 定位複雜系統的問題比簡單系統更加困難
2)、邏輯的複雜性
- 單元件承擔功能過多,導致邏輯複雜度升高
- 後續的功能修改會影響很大
- 使用了複雜的演算法難以實現修改和問題解決
如果簡單和複雜的都能滿足需求,最好選擇簡單的方案!
3、演化原則:演化優於一步到位. 架構設計沒有完美銀彈. 勿過度設計.
軟體架構同建築架構相似,但建築不可變,軟體可變, 例如:Windows的演化、Android的發展。
軟體架構類似於大自然“設計”的一個生物,通過演化適應環境,逐步變得強大。
- 首先滿足當前需要,解決當前最核心問題.
- 預測並併發未來可能存在的問題, 不斷迭代保留,不斷完善,
- 業務變化時,架構擴充套件、重構、甚至重寫。
不要貪大求全,分析清楚自身業務特點,快速落地,不斷完善演化。當然如果一開始系統就有很好的基礎設計, 未來可能更容易到達滿意的目標.
所有問題的前提要搞清楚我們今天面臨的業務量有多大,增長走勢是什麼樣,而且解決高併發的過程,一定是一個循序漸進逐步的過程。例如在初創公司的野蠻生長階段,業務場景和需求邊界很難把握,有時候根本不需要架構師,產品需要快速迭代和變現,需求頻繁更新,這個時候需要的是快速實現。這時候考慮如何做好架構設計, 如何微服務化, 可能會影響業務的發展.
網上的一張圖很經典,總結的非常好:
整個系統進化分為三個階段:
x軸,水平擴充套件階段,通過負載均衡伺服器不斷的橫向擴充應用伺服器,水平擴充套件最重要的問題是需要注意不用伺服器之間的如何保持session和會話同步,不能讓使用者在不通伺服器之間切換時有感知應用擴充套件後自然遇到的問題就是DB的瓶頸:連線數,iops等。
z軸,就是對資料庫的拆分,難度上了一個臺階,Sharding的基本思想就要把一個數據庫如何進行切分,可以分為水平切分和垂直切分,水平切分相對簡單,一主多從,多主都可以,根據業務的需要,多主切分設計時需要注意主鍵的關係,解決多寫在進行資料同步時候的衝突問題,垂直拆分更加複雜,一般都會涉及到架構邏輯的改造,需要引入中介軟體,來進行資料來源的管理,垂直拆分時把關係緊密(比如同一模組)的表切分出來放在一個庫上,或者通過hash進行拆分,從而將原有資料庫切分成類似矩陣一樣可以無限擴充的佇列。
y軸擴充套件,最後就是功能分解了,也就是我們講的微服務切分。微服務拆分將巨型應用按照功能模組分解為一組組不同的服務,淘寶的系統當年也經歷了這樣的過程,通過五彩石專案從單一的war包拆分成了今天的大家看到買家,賣家中心,交易等系統。
技術選型: 是否使用微服務架構設計
在司成長穩定以後, 業務模式和應用場景邊界都已經比較清晰,這個時候最需要對線上業務進行模組劃分,系統拆分重構,並做好相關高可用的措施,以保證系統的穩定,安全、高效地執行。這時候可能要考慮引入微服務.
在引入微服務前你要知道的事:
1、成本升高
引入微服務架構,需要對原來單一系統進行拆分,1到100以後多服務的部署會帶來成本的升高**
2、解決分散式事務一致性問題
以前單一的系統好處很多,一條sql解決完成所有業務邏輯,微服務做完一件事情需要涉及多系統呼叫,系統間網路的不確定性給結果帶來很多不確定性,如今天淘寶的系統,完成一次交易下單需要在上百個系統之間呼叫,如何保證系統的可靠性,以及核心資料如錢的最終一致性是設計之初就要想明白的,這裡大多都要藉助中介軟體來實現。
3、微服務的邏輯設計原則
隨著不斷拆分微服務,以及業務的迭代發展,系統之間極有可能出現混亂呼叫,所以微服務的頂層設計顯得尤為重要,架構師需要搞清楚微服務的架構模型。那核心的設計思想就在於如何進行服務的分層,以及服務的重用,通過分層將服務進行分配,上層服務包裝下層服務,下層服務負責原子性的操作,上層服務對下層服務進行業務性的組合編排,一定要理解業務,微服務拆分不是簡單的系統組合,再說一遍一定要理解業務,否則上層服務一定會出現大量的交叉呼叫,系統複雜度會指數級上升,好的微服務架構師一定是業務架構師,基於業務的建瓴,微服務設計三部曲,遵循自下而上的設計原則:
原子服務
首先確認最基本業務最維度的原子服務,原子服務定義就是大家都會最大化重用的功能,需要在應用內的閉環操作,沒有任何跨其他服務的分支邏輯,杜絕對其他服務的呼叫,有自己獨立的資料儲存,作為最底層服務抽象存在,以淘寶為例,賣家資料,賣家資料,訂單資料就屬於最基本的原子服務。
服務組合
在業務場景下,一個功能都需要跨越多個原子服務來完成一個動作。組合服務就是將業務邏輯抽象拆成獨立自主的域,域之間需要保持隔離,服務組合會使用到多個原子服務來完成業務邏輯,如淘寶的交易平臺會呼叫使用者,商品,庫存等系統。
業務編排
最外層就是面向使用者的業務流程,一個產品化的商業流程需要對組合服務進行邏輯編排來完成最終的業務結果,這個編排服務可以完全是自動化的,通過工作流引擎進行組合自動化來完成特定SOP定義,這對企業應用的自動化流程改進也很有意義。如淘寶類目的雙十一活動,通過對不通服務組合進行重用實現不通的營銷活動邏輯。
4、運維管理的複雜度提升
微服務讓應用數量增加很多,鏈路的整合、測試、部署都成為新的挑戰,以前一個war包解決的問題,需要通過多應用釋出來完成,釋出時服務之間的依賴影響,會導致功能不可用,測試階段的依賴性可能會讓用例跑不下去,這些都會是需要新考慮的問題,需要有平臺化的工具來支撐,目前阿里通過aone產品來保證從日常到預發到線上的持續整合交付。