若是如今讓你闡述一下什麼是「分佈式系統」,你腦子裏第一下跳出來的是什麼?我想,此時能夠用蘇東坡先生的一句詩,來形象地描述你們對分佈式系統的認識:html
橫當作嶺側成峯,遠近高低各不一樣。mysql
我以爲每一個人腦子裏一會兒涌現出來的確定是很是具象的東西,就像下面這些:sql
若是你一會兒想到的是XX中心、XX服務,意味着你把服務化的模式(SOA、ESB、微服務)和分佈式系統錯誤地劃上了等號。數據庫
那麼,什麼是「服務化」呢?服務化就像企業當中將相同崗位的人員劃分到同一個部門管理,以此來收斂特定的工做入口,再進行二次分配,以提升人員利用率和勞動成果的複用度。服務化的本質是「分治」,而「分治」的前提是先要拆,而後才談得上如何治。這時,高內聚、低耦合的思想在拆分過程當中起到了一個很是重要的做用,由於這能夠儘量地下降拆分後不一樣組件間進行協做的複雜度。因此重要的是「怎麼拆「,還有如何按部就班地拆,而這個過程當中你到底是採用了何種服務化模式(好比SOA、ESB、微服務等)並非關鍵。緩存
爲何說「怎麼拆」最重要呢?我來舉個例子,企業的組織架構包括三種模型:職能型、項目型、矩陣型。你能夠把這裏的企業理解爲一個「分佈式系統」,把後面的3種模型理解爲這個分佈式系統的3種形態。做爲這個「系統」的全部人,你須要考慮如何拆分它,才能使得各功能組件相互之間能夠更好地協做。假設,你要將一個總計10000名員工的企業按「職能型」拆分紅20個部門,獲得的結果是每一個部門500人。架構
這時,若是工做是流水線式的上下游關係。一個部門完工了再交給下一個部門。框架
那麼這時候是高內聚、低耦合的。由於一個工種只與另外一個工種產生了關聯,而且僅有一次。異步
但若是工做須要頻繁的由不一樣職能的人員同時進行,會致使同一個部門可能與多個部門產生聯繫。分佈式
那麼,這時是低內聚、高耦合的。由於一個工種須要和其餘多個工種產生關聯而且遠不止一次。函數
能夠看到服務化體現了「分治」的效果,這也是分佈式系統的核心思想,所以從「分治」這個本質上來看,服務化的確是分佈式系統,但分佈式系統不只僅停留在那些服務化的模式上。
我相信,你在工做中參與開發的任何軟件系統,處處都存在着須要拆分的地方,除非它的功能極簡到只須要計算一個1+1。好比,當咱們在電商平臺點擊「提交訂單」的時候,會涉及生成訂單、扣除積分、扣除庫存等等動做。電商系統初期全部的功能可能都在一個系統裏面,那麼這些操做能夠寫在一個方法體裏嗎?我想只要代碼可以成功運行,大部分人是不會管你怎麼寫的。可是若是這時須要增長一個紅包功能呢?相信你或多或少遇到過在幾百上千行代碼中去增改功能的事情,其中的痛苦應該深有體會。
要解決這個問題就是要作拆分,經過梳理、歸類,將不一樣的緊密相關的部分收斂到一個獨立的邏輯體中,這個邏輯體能夠是函數、類以及命名空間,等等。因此,從這個角度來講「分治」的問題其實早就存在咱們的工做中,就看咱們是否有去關注它了。所以,這並不僅是咱們在進行服務化時才須要考慮的問題。
那麼如何才能作好這個事情,更好的拆分能力正是咱們須要掌握的。若是隻是由於看到其餘人這麼拆,我也這麼拆,根據「二八原則」,或許「依樣畫葫蘆」能夠達到80%的契合度,可是每每那剩下的20%會是耗費咱們80%精力的「大麻煩」。要知道,只有掌握了核心主旨,才能更快地找到最理想的高內聚、低耦合方案。
「分佈式系統」是各類中間件嗎?
又或許,聽到分佈式系統,你想到了某某MQ框架、某某RPC框架、某某DAL框架,把運用中間件和分佈式系統錯誤地劃上了等號。
這裏須要搞清楚的是,中間件起到的是標準化的做用。中間件只是承載這些標準化想法的介質、工具,能夠起到引導和約束的效果,以此起到大大下降系統複雜度和協做成本的做用。咱們來分別看一下:
MQ框架標準化了不一樣應用程序間非實時異步通訊的方式。
RPC框架標準化了不一樣應用程序間實時通信的方式。
DAL(Data Access Layer,數據訪問層)框架標準化了應用程序和數據庫之間通信的方式。
因此,雖然分佈式系統中會運用中間件,但分佈式系統卻不只僅停留在用了什麼中間件上。你須要清楚每一類中間件背後是對什麼進行了標準化,它的目的是什麼,帶來了哪些反作用,等等。只有如此,你才能真正識別不一樣技術框架之間的區別,找到真正適合當前系統的技術框架。
那麼標準是拍腦殼決定的嗎?確定不是,正如前面所說每一次標準化都是有目的的,須要產生價值。好比,大部分中間件都具有這樣一個價值:
爲了在軟件系統的迭代過程當中,避免將精力過多地花費在某個子功能下衆多差別不大的選項中。
在現實中,這點更多時候出如今技術層面的中間件裏,好比,數據庫訪問框架的做用是爲了標準化操做不一樣數據庫的差別,使得上層應用程序不用糾結於該怎麼與mysql交互或者該怎麼與SQL SERVER交互。由於與業務相比,技術層面「穩定」多了,因此作標準化更有價值,更能得到長期收益。但「穩定」是相對的,哪怕單純在業務層面也存在相對穩定的部分。
好比,你能夠想象一下「盛飯」的場景,在大多數狀況下其中相對穩定的是什麼,不穩定的是什麼。想完以後看下面的示例。
... 基類:人 繼承基類的子類:男人、女人 基類:碗 繼承基類的子類:大碗、小碗、湯碗 基類:勺子 繼承基類的子類:鐵勺、陶瓷勺、塑料勺 function盛飯(參數人,參數碗,參數勺子){ do人拿起碗 do人拿起勺子 do人用勺子舀起飯 do人把勺子放到碗的上方並倒下 } ...
從這個示例裏咱們發現,不穩定的部分都已經成爲變量了,那麼剩下的這個方法體起到的做用和前面提到的中間件是同樣的,它標準化,標準化了盛飯的過程。因此識別相對穩定的部分是什麼,如何把它們提煉出來,而且圍繞這些點進行標準化,纔是咱們須要掌握的能力。而鍛鍊這個能力和須要這個能力的地方一樣並不侷限於分佈式系統。
列舉這些現象只是想說,咱們在認知一個分佈式系統的時候,內在勝於表象,掌握一個紮實的理論基本功更爲重要。並且,這些訓練場無處不在。
海市蜃樓般的「分佈式系統」
我相信,自從進入移動時代以來,各類高大上的系統架構圖愈來愈頻繁地出現,你的眼前充斥着各類主流、非主流的眼花繚亂的技術框架。你不禁得肅然起敬一番,心中吶喊着:「對,這就是我想去的地方,我想參與甚至實現一個這樣牛逼的分佈式系統,不再想天天只是增刪改查了。」
得不到的事物老是美好的,但每每咱們也會過分地高估它的美好。與此相似,高大上的架構圖背後呈現的系統的確也是一個成熟分佈式系統的樣貌,但咱們要清楚一點:羅馬不是一日建成的。
並且,「分佈式」這個詞只是意味着形態上是散列狀的,而「一分爲二」和「一分爲N」本質上並無區別。因此,不少小項目或者大型項目的初期所搭配的基礎套餐「單程序+單數據庫」,一樣能夠理解爲分佈式系統,其中遇到的問題不少一樣也存在於成熟的分佈式系統中。
想象一下,下面的場景是否在「單程序+單數據庫」項目中出現過?
log記錄執行成功,可是數據庫的數據沒發生變化;
進程內的緩存數據更新了,可是數據庫更新失敗了。
這裏咱們停頓30秒,思考一下爲何會出現這些問題?
這裏須要咱們先思考一下「軟件」是什麼。軟件的本質是一套代碼,而代碼只是一段文字,除了提供文字所表述的信息以外,自己沒法「動」起來。可是,想讓它「動」起來,使其可以完成一件咱們指定的事情,前提是須要一個宿主來給予它生命。這個宿主就是計算機,它可讓代碼變成一連串可執行的「動做」,而後經過數據這個「燃料」的觸發,「動」起來。這個持續的活動過程,又被描述爲一個運行中的「進程」。
那麼除了咱們開發的系統是軟件,數據庫也是軟件,前者負責運算,後者負責存儲運算後的結果(也可稱爲「狀態」),分工協做。
因此,「單程序+單數據庫」爲何也是分佈式系統這個問題就很明白了。由於咱們所編寫的程序運行時所在的進程,和程序中使用到的數據庫所在的進程,並非同一個。也所以致使了,讓這兩個進程(系統)完成各自的部分,然後最終完成一件完整的事,變得再也不像由單個個體獨自完成這件事那麼簡單。這就如「兩人三足」遊戲同樣,如何儘量地讓外部看起來像是一個總體、天然地前進。
因此,咱們能夠這麼理解,涉及多個進程協做才能提供一個完整功能的系統就是「分佈式系統」。
那麼再回到上面舉例的兩個場景,咱們在思考「單程序+單數據庫」項目中遇到的這些問題背後的緣由和解決它的過程時,與咱們在一個成熟的分佈式系統中的遭遇是同樣的,例如數據一致性。固然,這只是分佈式系統核心概念的冰山一角。
維基百科對「分佈式系統」的宏觀定義是這樣的:
分佈式系統是一種其組件位於不一樣的聯網計算機上的系統,而後經過互相傳遞消息來進行通訊和協調。爲了達到共同的目標,這些組件會相互做用。
咱們能夠再以大小關係來解釋它:把須要進行大量計算的工程數據分割成小塊,由多臺計算機分別計算,而後將結果統一合併得出數據結論的科學。這本質上就是「分治」。而「單程序+單數據庫」組合的系統也包含了至少兩個進程,「麻雀雖小五臟俱全」,這也是「分佈式系統」。
總結
如今,咱們搞清楚了,看待一個「分佈式系統」的時候,內在勝於表象。以及,只要涉及多個進程協做才能提供一個完整功能的系統,就是「分佈式系統」。
我相信還有不少其餘景象出現你的腦海中,但這大多數都是分佈式系統的本質產生的「化學反應」,進而造成的結果。若是停留在這些表象上,那麼咱們最終將沒法尋找到「分佈式系統」的本質,也就沒法獲得真正的「道」,更不會真正具有駕馭這些形態萬千的「分佈式系統」的能力。
因此,但願你在學習分佈式系統的時候,不要因追逐「術」而丟了「道」。沒有「道」只有「術」是空殼,最終會走火入魔,學得越多,會越混亂,處處都是矛盾和疑惑。
所以,咱們這個系列除了教給你在具體場景下的最佳實踐,還會和你講解爲何這樣作,以及該如何去權衡不一樣方案。不會過多的講述具體的技術框架,大部份內容圍繞理論展開,欲使每一個人可以掌握好這些分佈式中的基礎理論和思路,修煉好本身的內功。
我將在後續的文章中,以一個項目的初期到成熟期做爲路線圖,帶領你按部就班地深刻到分佈式系統中,層層遞進地去剝開它的本質,而且圍繞這個本質去思考(是什麼問題,有哪些方式能夠解決,何時該用何種種方式等等),讓你知其然且知其因此然,造成一套完整的知識體系,完成核心「骨架」的塑造。而在此以後,你本身在課外學習時,就能夠去填充「血肉」部分,逐漸豐滿本身。將來,你們的區別就在於胖一點和瘦一點,但只要能很好地完成工做,胖瘦又有何影響?