軟件架構編年史:單體架構
本文轉載自微信公眾號「逸言」,作者覃宇。轉載本文請聯系逸言公眾號。
混沌初開,單體始現……
默認的架構風格就是構建一個單體。我的意思是,最開始應用程序就只有一個文件,然后應用程序開始由多個文件組成,從 20 世紀 90 年代開始才出現由其它應用程序組成的應用(盡管20世紀80年代就開始了最初的嘗試)。
單體自己也在發生變化。當應用程序開始使用多個文件創建時,其實并沒有太多的思考,也沒有太多思考的必要,因為應用程序都相當簡單。當應用程序開始膨脹變得越來越復雜時,才會需要推敲應用程序背后有哪些文件需要創建,它們又該如何關聯。
模塊化軟件開發
模塊化編程是 20 世紀 60 年代末到 70 年代間提出的方案。它是從類到更粗粒度代碼單元的明確定義的進化。編程語言使用不同等級的明確性來實現模塊化。
例如,JAVA 在類這個層級的可見性有默認級別和 public 級別,默認級別意味著類只在它所屬的 package (模塊)內可見,而 public 級別意味著這個類在 package (模塊)內和 package (模塊)外都可見。
組件化軟件開發
組件是另一種模塊化風格。如我之前一篇文章(譯)所述,組件是按照領域概念劃分的模塊。理想情況下,它們是可以組成應用的獨立的“應用程序”。老生常談的例子是在 Unix 系統中廣泛使用的管道和過濾器架構,例如我們可以使用這樣的命令ps -ef | grep php。另外的例子就是 Netflix 將微服務作為應用的組件。
代碼的組織風格和模塊化軟件開發一樣,早在 20 世紀 60 年代末就已經存在了。
現代的單體
現在,單體架構風格就是簡單地意味著所有應用代碼被部署并運行在單一節點的單一進程中。我們認為它會用到模塊和組件,盡管事實往往并非如此。
這里有兩個關鍵詞“部署”和“節點”要好好地理解。第一個詞“部署”的意思是運行時代碼的組織方式,無論代碼在物理上是存儲在一個還是多個代碼庫之中。而第二個詞“節點”的意思是即便是在橫向擴展的情況下我們將應用部署到了多個服務器,它依然是一個單體。
在單一節點的服務器上,單體的所有模塊都被集中到同一個內存映像里,作為單一節點上的單個進程運行。通過標準進程調用在同一個棧和堆內進行模塊間的通信。單個的內存映像讓應用變成了單體。如果模塊在不同的進程中運行,通信就變成了 IPC (進程間調用)。由于模塊進入了不同的進程邊界,你將要面臨分布式計算的挑戰。這就進入了微服務的范疇。(感謝dban的反饋)。
盡管這種風格聲名狼藉,但它依然可以在大型應用中工作得很好。只是下面這些條件下表現得不足夠好:
- 不同的領域組件需要獨立可伸縮;
- 不同的組件需要不同的編程語言來編寫;
- 獨立可部署,因為我們的發布頻率比一個代碼庫的持續交付流水線要快,由于需要等待其它發布的部署導致自身發布的部署變慢,或者導致部署隊列增長太快無法及時響應。
這時,我們需要將單體按照面向服務的架構風格(接下來的文章中將詳細介紹)拆分成不同的應用程序。
反模式:大泥球/意大利面架構
“大泥球”又稱意大利面架構,是這種風格的反模式。這種反模式中,包結構和關系十分模糊,結構化的內聚和封裝完全沒有或極少,依賴毫無規則,子系統很難分辨,也很難修改和重構。系統晦澀、粘滯、脆弱、僵化:就是一個大泥球!
引用來源
- 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開發者/ThoughtWorks技術教練//譯者,熱衷于探究軟件開發的方方面面,從端到云,從工具到實踐。喜歡通過翻譯來學習和分享知識,譯作有《Kotlin實戰》、《領域驅動設計精粹》、《Serverless架構:無服務器應用與AWS Lambda》和《云原生安全與DevOps保障》。