分布式架构系统拆分原则、需求、微服务拆分步骤
為什么需要應用拆分
我以淘寶技術架構演進為例,淘寶從一個大系統(tǒng)工程向分布式架構演變過程,你就能很清楚的知道為什么要需要進行應用拆分。
1 人員的角度
維護一個代名工程Denali的百萬級代碼怪獸(雖然物理部署是分離的),從發(fā)布到上線,從人員的角度,百號人同時在一個工程上開發(fā),一旦線上出問題,所有代碼都需要回滾,從人員的角度,也基本忍受到了極致。
2業(yè)務的角度
淘寶包含太多業(yè)務:用戶、商品、交易、支付…等等,所有的代碼早期都在denali一個工程里,代碼已經嚴重影響到業(yè)務的效率,每個業(yè)務有各自的需求,需要給自己應用部署,各自開發(fā)需求。
3從架構的角度
從數(shù)據(jù)庫端oracle數(shù)據(jù)庫集中式架構的瓶頸問題,連接池數(shù)量限制(oracle數(shù)據(jù)庫大約提供5000個連接),數(shù)據(jù)庫的CPU已經到達了極限90%。數(shù)據(jù)庫端也需要考慮垂直拆分了。
4.急需走向一個大型的分布式時代,率先需要應用拆分
1)首先工程代碼垂直拆分
把整個工程代碼按照業(yè)務為單元進行垂直拆分。
淘寶按照業(yè)務為單位拆分成了類似這樣的系統(tǒng):UM(UserManger)、SM(ShopManager)..等等幾十個工程代碼。
2 )應用服務拆分
按照業(yè)務為單位,把所有調用相關的接口以業(yè)務為單元進行拆分。
比如,一個店鋪系統(tǒng),需要訪問一個用戶的頭像的接口,用戶頭像的接口是獨立部署在用戶中心(UIC)這邊的集群服務器上的。隨著拆分的進行,淘寶的業(yè)務接口中心就變成了:UIC(用戶中心服務)、SIC(店鋪中心服務)等等以業(yè)務為單元部署的集群。
最終就演變成下圖,按照業(yè)務為單位拆分和部署服務,用戶中心、商品中心等:
總之,系統(tǒng)拆分是單體程序向分布式系統(tǒng)演變的關鍵一步,也是很重要的一步,拆分的好壞直接關系到未來系統(tǒng)的擴展性、可維護性和可伸縮性等,拆分工作不難理解,但是如何正確拆分、有什么樣的方法和原則能幫助我們拆分得到一個我們理想中的系統(tǒng):高可用、可擴展、可維護、可伸縮的分布式系統(tǒng)。
以下主要再從拆分需求、拆分原則和拆分步驟談起:
拆分需求
1、組織結構變化
從最初的一個團隊逐漸成長并拆分為幾個團隊,團隊按照業(yè)務線不同進行劃分,為了減少各個業(yè)務系統(tǒng)和代碼間的關聯(lián)和耦合,幾個團隊不再可能共同向一個代碼庫中提交代碼,必須對原有系統(tǒng)進行拆分,以減少團隊間的干擾。
2、安全
這里所指的安全不是系統(tǒng)級別的安全,而是指代碼或成果的安全,尤其是對于很多具有核心算法的系統(tǒng),為了代碼不被泄露,需要對相關系統(tǒng)進行模塊化拆分,隔離核心功能,保護知識產權。
3、替換性
有些產品為了提供差異化的服務,需要產品具有可定制功能,根據(jù)用戶的選擇自由組合為一個完整的系統(tǒng),比如一些模塊,免費用戶使用的功能與收費用戶使用的功能肯定是不一樣的,這就需要這些模塊具有替換性,判斷是免費用戶還是收費用戶使用不同的模塊組裝,這也需要對系統(tǒng)進行模塊化拆分。
4、交付速度
單體程序最大的問題在于系統(tǒng)錯綜復雜,牽一發(fā)而動全身,也許一個小的改動就造成很多功能沒辦法正常工作,極大的降低了軟件的交付速度,因為每次改動都需要大量的回歸測試確保每個模塊都能正確工作,因為我們不清楚改動會影響到什么,所以需要做大量重復工作,增加了測試成本。這時候就需要對系統(tǒng)進行拆分,理清各個功能間的關系并解耦。
5、技術需求
1)單體程序由于技術棧固定,尤其的是比較龐大的系統(tǒng),不能很方便的進行技術升級,或者說對引入新技術或框架等處于封閉狀態(tài);每種語言都有自己的特點,單體程序沒有辦法享受到其它語言帶來的便利;對應到團隊中,團隊技術相對比較單一。
2)相比于基于業(yè)務的垂直拆分,基于技術的橫向拆分也很重要,使用數(shù)據(jù)訪問層可以很好的隱藏對數(shù)據(jù)庫的直接訪問、減少數(shù)據(jù)庫連接數(shù)、增加數(shù)據(jù)使用效率等;橫向拆分可以極大的提高各個層級模塊的重用性。
6、業(yè)務需求:由于業(yè)務上的某些特殊要求,比如對某個功能或模塊的高可用性、高性能、可伸縮性等的要求,雖然也可以將單體整體部署到分布式環(huán)境中實現(xiàn)高可用、高性能等,但是從系統(tǒng)維護的角度來考慮,每次改動都要重新部署所有節(jié)點,顯然會增加很多潛在的風險和不確定定性因素,所以有時候不得不選擇將那些有特殊要求的功能從系統(tǒng)中抽取出來,獨立部署和擴展。
如何拆分
1.拆分原則
單一職責
服務粒度適中
考慮團隊結構
以業(yè)務模型切入
演進式拆分
避免環(huán)形依賴和雙向依賴
2.分布式應用拆分實戰(zhàn)
下面是拆分代碼過程實踐經驗:
1).設計module骨架
module骨架的設計是基礎,影響最終拆分結果,拆分成功的向導。按照技術,業(yè)務,部署打包,測試這幾個維度來規(guī)劃設計,下面是一個參考。
最終骨架模型層級:
root web app
webapp //war module,打包為單體war,整體部署
micro-services //微服務pom module
user-service
customer-service
order-service
other-service
api-gateway
biz //業(yè)務相關的module
entitys //所有實體類
biz-base //一些無法拆分的代碼上有依賴的服務
biz-user //用戶業(yè)務
biz-customer //客戶業(yè)務
biz-order //訂單業(yè)務
…
commons
async-framework //一部框架
utils //工具類
2).拆分技術commons
作為第一步,先對整個工程按業(yè)務和功能進行了maven多module的拆分。
首先是分離出技術上的commons,感覺這應該是最好拆分的了,把相關的類重構到一個包里,在分離出一個module即可。
3).拆分entity
很多在業(yè)務代碼上都會共享entity類,通常沒法也沒法把entity類分門別類,最簡單就是把所有的entity類放到一個module,誰需要誰依賴的原則。entity類也沒有太多jar依賴和業(yè)務依賴,也不會形成污染源。
4)公共業(yè)務
同commons和entity方法,不在復述,也被各個業(yè)務依賴,這種業(yè)務大部分是過渡性的,在未來迭代演進時可以通過其他方式抽象集成。
5)拆分業(yè)務代碼
拆分業(yè)務是最痛苦的事情了,這個要看原來的代碼整潔度和互相依賴程度,一般采取2中方法:
新建業(yè)務module,加入基礎module的pom依賴,再從源module復制和該業(yè)務module相關的代碼(包括單元測試代碼)過來,解決編譯錯誤和單元測試錯誤,完成本業(yè)務拆分。
從源module復制一個新業(yè)務module,保持代碼一致,先刪除和本義務無關的代碼(包括單元測試代碼),再刪除無關的pom依賴,解決編譯錯誤和單元測試錯誤,完成本業(yè)務拆分。
選擇哪種方法,可以根據(jù)代碼整潔度和互相依賴程度,如果代碼很整潔且相互依賴較弱,可以采取前者,否則就采取后者。
6)拆分微服務
有了以上的拆分基礎,可以在合適的業(yè)務迭代將各個微服務module遷移到不同的代碼倉庫,完成進一步隔離管理。
微服務架構框架
業(yè)界開源微服務架構框架提供了微服務的關鍵思路,詳細請查看微服務Dubbo和SpringCloud架構設計、優(yōu)劣勢比較
Dubbo是Alibaba開源的分布式服務框架,它最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地松耦合)。
Spring Cloud是一個微服務框架,相比Dubbo等RPC框架,Spring Cloud提供的全套的分布式系統(tǒng)解決方案。
微服務架構是互聯(lián)網技術發(fā)展的必然結果,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協(xié)調、互相配合,為用戶提供最終價值。
分布式架構之應用拆分總結:
1.明確拆分原則和拆分需求。
2.梳理出業(yè)務模塊和之間的依賴關聯(lián)關系。
3.按照業(yè)務為單位,拆分實體、以及應用工程單獨部署。
4.按照業(yè)務為單位拆分應用服務,避免環(huán)形依賴和雙向依賴。
5.抽離出公用的接口、實體,以及服務單獨部署為公用服務。
總結
以上是生活随笔為你收集整理的分布式架构系统拆分原则、需求、微服务拆分步骤的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 了解iOS消息推送一文就够:史上最全iO
- 下一篇: Axure RP 8.0软件安装教程