軟件架構(gòu)編年史:?jiǎn)误w架構(gòu)
本文轉(zhuǎn)載自微信公眾號(hào)「逸言」,作者覃宇。轉(zhuǎn)載本文請(qǐng)聯(lián)系逸言公眾號(hào)。
混沌初開(kāi),單體始現(xiàn)……
默認(rèn)的架構(gòu)風(fēng)格就是構(gòu)建一個(gè)單體。我的意思是,最開(kāi)始應(yīng)用程序就只有一個(gè)文件,然后應(yīng)用程序開(kāi)始由多個(gè)文件組成,從 20 世紀(jì) 90 年代開(kāi)始才出現(xiàn)由其它應(yīng)用程序組成的應(yīng)用(盡管20世紀(jì)80年代就開(kāi)始了最初的嘗試)。
單體自己也在發(fā)生變化。當(dāng)應(yīng)用程序開(kāi)始使用多個(gè)文件創(chuàng)建時(shí),其實(shí)并沒(méi)有太多的思考,也沒(méi)有太多思考的必要,因?yàn)閼?yīng)用程序都相當(dāng)簡(jiǎn)單。當(dāng)應(yīng)用程序開(kāi)始膨脹變得越來(lái)越復(fù)雜時(shí),才會(huì)需要推敲應(yīng)用程序背后有哪些文件需要?jiǎng)?chuàng)建,它們又該如何關(guān)聯(lián)。
模塊化軟件開(kāi)發(fā)
模塊化編程是 20 世紀(jì) 60 年代末到 70 年代間提出的方案。它是從類到更粗粒度代碼單元的明確定義的進(jìn)化。編程語(yǔ)言使用不同等級(jí)的明確性來(lái)實(shí)現(xiàn)模塊化。
例如,JAVA 在類這個(gè)層級(jí)的可見(jiàn)性有默認(rèn)級(jí)別和 public 級(jí)別,默認(rèn)級(jí)別意味著類只在它所屬的 package (模塊)內(nèi)可見(jiàn),而 public 級(jí)別意味著這個(gè)類在 package (模塊)內(nèi)和 package (模塊)外都可見(jiàn)。
組件化軟件開(kāi)發(fā)
組件是另一種模塊化風(fēng)格。如我之前一篇文章(譯)所述,組件是按照領(lǐng)域概念劃分的模塊。理想情況下,它們是可以組成應(yīng)用的獨(dú)立的“應(yīng)用程序”。老生常談的例子是在 Unix 系統(tǒng)中廣泛使用的管道和過(guò)濾器架構(gòu),例如我們可以使用這樣的命令ps -ef | grep php。另外的例子就是 Netflix 將微服務(wù)作為應(yīng)用的組件。
代碼的組織風(fēng)格和模塊化軟件開(kāi)發(fā)一樣,早在 20 世紀(jì) 60 年代末就已經(jīng)存在了。
現(xiàn)代的單體
現(xiàn)在,單體架構(gòu)風(fēng)格就是簡(jiǎn)單地意味著所有應(yīng)用代碼被部署并運(yùn)行在單一節(jié)點(diǎn)的單一進(jìn)程中。我們認(rèn)為它會(huì)用到模塊和組件,盡管事實(shí)往往并非如此。
這里有兩個(gè)關(guān)鍵詞“部署”和“節(jié)點(diǎn)”要好好地理解。第一個(gè)詞“部署”的意思是運(yùn)行時(shí)代碼的組織方式,無(wú)論代碼在物理上是存儲(chǔ)在一個(gè)還是多個(gè)代碼庫(kù)之中。而第二個(gè)詞“節(jié)點(diǎn)”的意思是即便是在橫向擴(kuò)展的情況下我們將應(yīng)用部署到了多個(gè)服務(wù)器,它依然是一個(gè)單體。
在單一節(jié)點(diǎn)的服務(wù)器上,單體的所有模塊都被集中到同一個(gè)內(nèi)存映像里,作為單一節(jié)點(diǎn)上的單個(gè)進(jìn)程運(yùn)行。通過(guò)標(biāo)準(zhǔn)進(jìn)程調(diào)用在同一個(gè)棧和堆內(nèi)進(jìn)行模塊間的通信。單個(gè)的內(nèi)存映像讓應(yīng)用變成了單體。如果模塊在不同的進(jìn)程中運(yùn)行,通信就變成了 IPC (進(jìn)程間調(diào)用)。由于模塊進(jìn)入了不同的進(jìn)程邊界,你將要面臨分布式計(jì)算的挑戰(zhàn)。這就進(jìn)入了微服務(wù)的范疇。(感謝dban的反饋)。
盡管這種風(fēng)格聲名狼藉,但它依然可以在大型應(yīng)用中工作得很好。只是下面這些條件下表現(xiàn)得不足夠好:
- 不同的領(lǐng)域組件需要獨(dú)立可伸縮;
- 不同的組件需要不同的編程語(yǔ)言來(lái)編寫;
- 獨(dú)立可部署,因?yàn)槲覀兊陌l(fā)布頻率比一個(gè)代碼庫(kù)的持續(xù)交付流水線要快,由于需要等待其它發(fā)布的部署導(dǎo)致自身發(fā)布的部署變慢,或者導(dǎo)致部署隊(duì)列增長(zhǎng)太快無(wú)法及時(shí)響應(yīng)。
這時(shí),我們需要將單體按照面向服務(wù)的架構(gòu)風(fēng)格(接下來(lái)的文章中將詳細(xì)介紹)拆分成不同的應(yīng)用程序。
反模式:大泥球/意大利面架構(gòu)
“大泥球”又稱意大利面架構(gòu),是這種風(fēng)格的反模式。這種反模式中,包結(jié)構(gòu)和關(guān)系十分模糊,結(jié)構(gòu)化的內(nèi)聚和封裝完全沒(méi)有或極少,依賴毫無(wú)規(guī)則,子系統(tǒng)很難分辨,也很難修改和重構(gòu)。系統(tǒng)晦澀、粘滯、脆弱、僵化:就是一個(gè)大泥球!
引用來(lái)源
- 1997 – Brian Foote, Joseph Yoder – Big Ball of Mud
- 2012 – Len Bass, Paul Clements, Rick Kazman –Software Architecture in Practice
- 2017 – Herberto Graça – Microservices architecture: What the gurus say about it
- 2017 – Herberto Graca –Software Architecture Premises
- 2017* – Wikipedia –Modular programming
- 2017* – Wikipedia –Component-based software engineering
覃宇,Android開(kāi)發(fā)者/ThoughtWorks技術(shù)教練//譯者,熱衷于探究軟件開(kāi)發(fā)的方方面面,從端到云,從工具到實(shí)踐。喜歡通過(guò)翻譯來(lái)學(xué)習(xí)和分享知識(shí),譯作有《Kotlin實(shí)戰(zhàn)》、《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)精粹》、《Serverless架構(gòu):無(wú)服務(wù)器應(yīng)用與AWS Lambda》和《云原生安全與DevOps保障》。