為什麼應用拆分
1 人員的角度。
維護一個代名工程Denali的百萬級代碼怪獸(雖然實體部署是分離的),從釋出到上線,從人員的角度,百号人同時在一個工程上開發,一旦線上出問題,所有代碼都需要復原,從人員的角度,也基本忍受到了極緻。
2 業務的角度
淘寶包含太多業務:使用者、商品、交易、支付…等等,所有的代碼早期都在denali一個工程裡,代碼已經嚴重影響到業務的效率,每個業務有各自的需求,需要給自己應用部署,各自開發需求。
3 從架構的角度
從資料庫端oracle資料庫集中式架構的瓶頸問題,連接配接池數量限制(oracle資料庫大約提供5000個連接配接),資料庫的CPU已經到達了極限90%。資料庫端也需要考慮垂直拆分了。
4.急需走向一個大型的分布式時代,率先需要應用拆分。
1 )首先工程代碼垂直拆分
把整個工程代碼按照業務為單元進行垂直拆分。
淘寶按照業務為機關拆分成了類似這樣的系統:UM(UserManger)、SM(ShopManager)..等等幾十個工程代碼。
2 )應用服務拆分
按照業務為機關,把所有調用相關的接口以業務為單元進行拆分。
比如,一個店鋪系統,需要通路一個使用者的頭像的接口,使用者頭像的接口是獨立部署在使用者中心(UIC)這邊的叢集伺服器上的。随着拆分的進行,淘寶的業務接口中心就變成了:UIC(使用者中心服務)、SIC(店鋪中心服務)等等以業務為單元部署的叢集。
最終就演變成下圖,按照業務為機關拆分和部署服務,使用者中心、商品中心等:總之,系統拆分是單體程式向分布式系統演變的關鍵一步,也是很重要的一步,拆分的好壞直接關系到未來系統的擴充性、可維護性和可伸縮性等,拆分工作不難了解,但是如何正确拆分、有什麼樣的方法和原則能幫助我們拆分得到一個我們理想中的系統:高可用、可擴充、可維護、可伸縮的分布式系統。
拆分需求
1、組織結構變化:從最初的一個團隊逐漸成長并拆分為幾個團隊,團隊按照業務線不同進行劃分,為了減少各個業務系統和代碼間的關聯和耦合,幾個團隊不再可能共同向一個代碼庫中送出代碼,必須對原有系統進行拆分,以減少團隊間的幹擾。
2、安全:這裡所指的安全不是系統級别的安全,而是指代碼或成果的安全,尤其是對于很多具有核心算法的系統,為了代碼不被洩露,需要對相關系統進行子產品化拆分,隔離核心功能,保護知識産權。
3、替換性:有些産品為了提供差異化的服務,需要産品具有可定制功能,根據使用者的選擇自由組合為一個完整的系統,比如一些子產品,免費使用者使用的功能與收費使用者使用的功能肯定是不一樣的,這就需要這些子產品具有替換性,判斷是免費使用者還是收費使用者使用不同的子產品組裝,這也需要對系統進行子產品化拆分。
4、傳遞速度:單體程式最大的問題在于系統錯綜複雜,牽一發而動全身,也許一個小的改動就造成很多功能沒辦法正常工作,極大的降低了軟體的傳遞速度,因為每次改動都需要大量的回歸測試確定每個子產品都能正确工作,因為我們不清楚改動會影響到什麼,是以需要做大量重複工作,增加了測試成本。這時候就需要對系統進行拆分,理清各個功能間的關系并解耦。
AKF拆分原則
業界對于可擴充系統架構設計有一個樸素的理念:通過加機器就可以解決容量和可用性問題。
這一理念在雲計算概念瘋狂流行的今天,得到了廣泛的認可,對于一個規模迅速增長的系統而言,容量和性能問題當然是首當其沖的。但随着時間的向前,系統規模的增長,除了面對性能與容量的問題外,還要面對功能與子產品數量上的增長帶來的系統複雜性問題以及業務的變化帶來的提供差異化服務的問題。
然而許多系統在架構設計時為充分考慮這些問題,導緻系統重構成為常态,而影響業務傳遞能力,還浪費人力财力。對此《可擴充藝術》一書提出了一個系統可擴充模型--AKF可擴充立方(Scalability Cube)。

Y軸(功能)關注應用中功能劃分,基于不同的業務拆分
Y軸擴充會将龐大的整體應用拆分為多個服務,每個服務實作一組相關的功能,如訂單管理、客戶管理等。在工程上常見的方案是服務化架構(SOA),比如對于一個電子商務平台,我們可以拆分成不同的服務,組成類似下面的架構:
但通過上圖可以發現,當服務數量增多時,服務調用關系變得複雜,為系統添加一個新功能,要調用的服務數變得不可控,由此引發了服務管理上的混亂,是以一般情況下,需要采用服務注冊的機制形成服務網關來進行服務治理
X軸(水準擴充)關注水準擴充,也就是“加速器解決問題”
X軸擴充與我們前面樸素理念是一緻的,通過絕對平等的複制服務與資料,以解決容量與可用性的問題,其實就是将微服務運作多個執行個體,做叢集加負載均衡的模式。
為了提升單個服務的可用性與容量,對每一個服務進行X軸擴充劃分。
Z軸(資料分區)關注服務與資料的優先級劃分,如按地域劃分
Z軸擴充通常是指基于請求者或使用者獨特的需求,進行系統劃分,并使得劃分出來的子系統互相隔離但又是完整的。以生産汽車的工廠來舉例:福特公司為了發展在中國的業務,或者利用中國的廉價勞動力,在中國建立一個完整的子工廠,與美國工廠一樣,負責完整的汽車生産。這就是一種Z 軸擴充。
工程領域常見的Z軸擴充有以下兩種方案
1,單元化架構
在分布式服務設計領域,一個單元Cell就是滿足某個分區所有業務操作的自包含閉環。如上面我們說到的Y軸擴充的SOA架構。用戶端對服務端節點的選擇一般是随機的,但是,如果在此上加Z軸擴充,那服務節點的選擇将不再是随機的,而是每個單元自成一體。
2,資料分區
為了性能資料安全上的考慮,我們将一個完整的資料集按一定次元劃分出不同的子集。一個分區(Shard),就是整體資料集的一個子集。比如用尾号來劃分使用者,那同樣尾号的那部分使用者就可以認為是同一個分區,資料分區一般包括以下幾種資料劃分形式:
資料類型:如業務類型
資料範圍:如時間段、使用者ID