一、架構(gòu)的發(fā)展歷程
我堅定的認(rèn)為要深刻的理解一項技術(shù)光靠網(wǎng)上一兩張按照各項維度對比的表格是不夠的,而是要了解這些技術(shù)出現(xiàn)的歷史背景:他們的出現(xiàn)到底是解決了什么問題,又帶來了什么新的問題,最后又因何而被淘汰。下面這部分內(nèi)容參考《鳳凰架構(gòu)》以及Martin Fowle等人一些文章進(jìn)行整理,一起來看下歷史的浪潮是如何推動架構(gòu)的演進(jìn)。
1.原始分布式時代
首先介紹的是竟然是“分布式”而不是“單體”這有些反常識,然而事實上分布式確實出現(xiàn)的比單體早,“單體”這個名稱是在微服務(wù)開始流行之后“事后追認(rèn)”所形成的概念,在單體出現(xiàn)之前分布式早已流行,并且成果斐然。
1971年Intel公司設(shè)計了世界上第一臺微型計算機(jī)MCS-4,開創(chuàng)了微型計算機(jī)的新時代,計算機(jī)逐步從專業(yè)的科研設(shè)備轉(zhuǎn)變?yōu)槠髽I(yè)的生產(chǎn)設(shè)備。但是微型計算機(jī)用于商業(yè)生產(chǎn)面臨一個非常大的問題:計算機(jī)硬件有限的運算處理能力,直接限制在單臺計算機(jī)上信息系統(tǒng)軟件能夠達(dá)到的最大規(guī)模。如果你生在這個時代,相信也能自然而然想到這一問題的解決思路:“人多力量大”、”眾人拾柴火焰高“,樸素的真理適用于任何地方,當(dāng)時高校、研究機(jī)構(gòu)、企等不約而同的開始探索“使用多臺計算機(jī)共同協(xié)作來支撐同一套軟件系統(tǒng)”的方案,并取得了一系的成果。談分布式必然繞不開遠(yuǎn)程調(diào)用,所以下面以遠(yuǎn)程調(diào)用為例談一下這一時期的探索成果有什么局限性,又產(chǎn)生了哪些深淵的影響。
通過多臺計算機(jī)分布式協(xié)同支撐提升系統(tǒng)規(guī)模
大家應(yīng)該了解“UNIX系統(tǒng)的版本戰(zhàn)爭”這一故事,為了避免相同的“戰(zhàn)爭”重演,負(fù)責(zé)制定 UNIX 系統(tǒng)技術(shù)標(biāo)準(zhǔn)的開放軟件基金會與主流計算機(jī)廠商共同制訂了DCE/RPC這一影響深遠(yuǎn)的遠(yuǎn)程服務(wù)調(diào)用規(guī)范,它也是公認(rèn)的現(xiàn)代 RPC 鼻祖之一。因為開放軟件基金會本身就負(fù)責(zé)UNIX 系統(tǒng)技術(shù)標(biāo)準(zhǔn)的制定,在這個背景下,DCE/RPC帶著濃厚的UNIX“簡單優(yōu)先原則”的設(shè)計哲學(xué),預(yù)設(shè)分布式環(huán)境中的服務(wù)調(diào)用、資源訪問等操作盡可能透明,使開發(fā)人員不必過于關(guān)注他們訪問的方法或資源是位于本地還是遠(yuǎn)程。
然而這個過于理想化的目標(biāo)在當(dāng)時面臨著太多的技術(shù)難題,“遠(yuǎn)程調(diào)用”與“本地調(diào)用”相比復(fù)雜程度完全不可同日而語:服務(wù)發(fā)現(xiàn)、負(fù)載均衡、熔斷、隔離、降級、認(rèn)證、授權(quán)等一系列的問題亟待解決。令人敬佩的是面對重重困難,DCE從無到有構(gòu)建了大量的協(xié)議來解決這些問題,真的做到了相對“透明”,但是分布式還有一個致命的問題——網(wǎng)絡(luò)所帶來的性能問題。
我們來推演一下:硬件性能不足——>采用分布式服務(wù)——>分布式的遠(yuǎn)程調(diào)用導(dǎo)致性能降低(與解決硬件性能不足的初心相悖)——>通過合并多個請求等方式刻意(開發(fā)人員需要意識到自己在寫分布式程序,與DCE透明簡單相悖)降低網(wǎng)絡(luò)性能損耗——>人的能力成為軟件規(guī)模的約束。這時候分布式從結(jié)果來看并不成功,設(shè)計向性能妥協(xié)讓簡單透明成為一句空話。
當(dāng)我們玩游戲打BOSS時,喊人解決不了問題還有另外個方法——氪金,20世紀(jì)80年代摩爾定律穩(wěn)定發(fā)揮,微型計算機(jī)的性能以每兩年即增長一倍的驚人速度提升,既然分布式充滿了矛盾與妥協(xié),那就加錢換更好的機(jī)器,單體時代到來。
通過提升單臺計算機(jī)性能提升系統(tǒng)規(guī)模
2.單體架構(gòu)時代
在微服務(wù)出現(xiàn)之前“單體”都不認(rèn)為是架構(gòu),因為他太“簡單”、太“自然”了,以至于我想找到一本關(guān)于單體最佳實踐的書籍都沒有找到?,F(xiàn)在很多書籍把單體當(dāng)做“毒瘤”,甚至?xí)霈F(xiàn)微服務(wù)比單體先進(jìn)的觀點,然而事實上真的如此嗎?
首先,我們先要明確單體是什么:“單體”只是表明系統(tǒng)中主要的過程調(diào)用都是進(jìn)程內(nèi)通信,不會發(fā)生進(jìn)程間通信,僅此而已。那么進(jìn)程內(nèi)調(diào)用是罪惡嗎?是毒瘤嗎?那肯定不是的?,F(xiàn)實中不會有人對你說:你這個"Hello, World!"程序不能用單體,因為單體架構(gòu)是毒瘤。
有個“單體不便于擴(kuò)展“的論調(diào)非常流行,我們著重討論下這個觀點是否準(zhǔn)確。我們從性能擴(kuò)展和功能擴(kuò)展兩個方便說。先說性能擴(kuò)展:這太簡單了,把一個服務(wù)部署多個副本,前面加一個負(fù)載均衡服務(wù)器來均分流量,這是不是就實現(xiàn)了擴(kuò)展?再說功能擴(kuò)展:縱向上我從來沒見到哪個大型系統(tǒng)代碼是不分層的,用過Spring都知道寫一個服務(wù)基本上默認(rèn)按照MVC模式分層以便于擴(kuò)展;而橫向上我們也可以從功能等維度拆分為不同模塊(模塊之間不進(jìn)行通信或者進(jìn)行少量的通信,注意:拆分模塊不代表不是單體服務(wù),單體服務(wù)也不表示系統(tǒng)只有一個模塊),各模塊完全可以獨立迭代。從這個角度來看單體服務(wù)在“可擴(kuò)展”這一點上也不輸與微服務(wù),甚至在開發(fā)、調(diào)試等方面更優(yōu)。當(dāng)前單體服務(wù)也有其局限性,比如有個C++實現(xiàn)的系統(tǒng)要實現(xiàn)部分AI功能,明顯Python更有優(yōu)勢,C++中執(zhí)行Python雖然可以實現(xiàn),但是顯然不如微服務(wù)獨立一個Python模塊來的優(yōu)雅?,F(xiàn)在回來看“單體服務(wù)不便于擴(kuò)展”這個觀點并不完全正確。
“罪惡的單體”是“大型的單體系統(tǒng)”,而“大單體服務(wù)”的主要罪惡在于隔離性。舉一個例子,不小心寫了一個BUG會導(dǎo)致程序崩潰,如果是微服務(wù)只會導(dǎo)致一個模塊崩潰,影響的范圍也僅僅是依賴這個模塊的功能,可是如果是單體服務(wù),所有代碼都共享著同一個進(jìn)程空間,某一處崩潰直接導(dǎo)致整個進(jìn)程崩潰,那影響的范圍就大了。到這里我們可以簡單的說:單體服務(wù)在同一進(jìn)程更簡單、高效,其代價是損失了隔離能力以及技術(shù)擴(kuò)展性。至于這兩點誰輕誰重不可一概而論,要看你的系統(tǒng)到底是一個小賣店還是一個大超市了。
既然單體和微服務(wù)各有優(yōu)劣,為什么后來微服務(wù)潮流滾滾而來?互聯(lián)網(wǎng)是不斷發(fā)展的,隨著微型計算機(jī)的普及,軟件系統(tǒng)的功能越來越多,對應(yīng)的開發(fā)團(tuán)隊規(guī)模也越來越大,我們逐步進(jìn)入了“大兵團(tuán)作戰(zhàn)”時代,這時候“墨菲定律”+“黑天鵝事件”對系統(tǒng)可用性影響越來越大。
構(gòu)建一個大規(guī)模但依然可靠的軟件系統(tǒng)非常難。根據(jù)墨菲定律可能發(fā)生的事(BUG)就一定會發(fā)生,再疊加不可預(yù)測的“黑天鵝事件”,隨著研發(fā)團(tuán)隊的規(guī)模不斷擴(kuò)大,系統(tǒng)不可用的概率會被無限放大,舉個極端點的例子:假如一個公司有10萬人,每個人寫出系統(tǒng)的可用性都能達(dá)到99.999%,可是當(dāng)他們共同協(xié)作寫一個單體服務(wù)時,那么系統(tǒng)的可用性就是99.999%的10萬次方,約等于36.8%,這個系統(tǒng)簡直不可用,更何況人是不可靠的,這時候單體服務(wù)隔離性差的缺點凸顯。微服務(wù)把構(gòu)筑可靠系統(tǒng)觀點從“追求盡量不出錯”轉(zhuǎn)變?yōu)椤俺鲥e是必然”,通過拆分服務(wù)以減少異常的影響范圍,關(guān)于微服務(wù)為什么可以提升系統(tǒng)的可用性可以用一個例子幫助理解:人體系統(tǒng)由一個個的不可靠的細(xì)胞(微服務(wù))組成,大多數(shù)情況下一個或者一群微服務(wù)(細(xì)胞)的崩潰并不會影響我們的生命,我們的人體系統(tǒng)就是用不可靠部件構(gòu)造的可靠的系統(tǒng)例子。