Categories
程式開發

如何尋找最佳架構,單體架構還是微服務?


通過觀察IT社區的現狀,Kamil Grzybek認為大多數新項目都採用了微服務架構實現。但是,他認為IT行業正在犯一個錯誤,即我們採用微服務僅僅是因為相信它能夠解決單體應用中的所有問題。與之相反,Grzybek推薦關注架構驅動力(architectural driver),他強調每種架構都有其優點和缺點,都會解決一些問題,但是會帶來新的問題。在他的系列文章,他已經描述了模塊化單體的基本概念和屬性,以及導致特定架構的驅動力

Grzybek是位於華沙的ITSG Global的架構師和團隊領導,他首先指出術語單體系統和單體架構通常用來描述所有的組成部分都放到一個部署單元的系統,但是這些術語通常也會假定其所有的組成部分是相互交織在一起的,而不是由架構上獨立的組件所組成,這些組成部分互相連接、互相依存,而不是松耦合的。他認為這是個非常負面的描述,並不是單體的終極屬性。相反,他將單體定義為單純有且僅有一個部署單元的系統。

為了實現模塊化,進而實現模塊化的架構,Grzybek指出必須要有獨立且可替換的模塊,每個模塊必須要有定義好的接口並實現接口所描述的功能需要的全部內容。模塊從來都不是完全獨立的,它總會依賴其他的東西。但是,依賴要盡可能匹配松耦合,強內聚的原則。為了確定模塊的獨立性和可替換性,我們必須關註三個元素:依賴的數量、這些依賴的強度以及它所依賴的模塊的穩定性。

系統中的變更通常針對的是業務功能,而不是技術部分。因此,模塊應該從業務的角度提供完整的特性集,以便更加自治和獨立。它還應該有一個定義良好的接口,也就是定義模塊能夠做什麼的契約,並將它的實現的隱藏並封裝起來。 Grzybek提到,封裝是模塊化不可分割的一個要素。

架構驅動力指的是對架構有著重要影響的需求集,Grzybek在這個定義中參考了Michael Keeling。 Grzybek將驅動力分成了四個主要類別:功能性需求定義了系統要解決什麼問題以及如何解決;質量屬性定義了質量,比如可維護性和可擴展性;技術約束是關於工具限制、團隊經驗和技術標準的;最後,業務約束則是關於預算、硬性截止時間的。

Grzybek強調所有的架構驅動力都是彼此關聯的,過於關注其中的某一個,往往會導致顧此失彼。他認為,系統的軟件架構師就是要在不同的驅動力之間不停地做出選擇,Grzybek指出,並沒有預先定義好的正確方案,並不存在所謂的銀彈。

在對比模塊化單體和微服務架構時,常見的架構驅動力就是複雜程度。 Grzybek發現模塊化單體要比分佈式系統複雜程度更低。高複雜性會降低可維護性、可讀性和可觀察性。它也會需要更有經驗的團隊、更高級的基礎設施和特定的組織文化。如果簡單性是一個關鍵的架構驅動力的話,那麼他強烈建議團隊要首先考慮單體形式並參考Martin Fowler的文章:單體優先

在文章中,Grzybek還討論了其他的驅動力,包括生產力、可部署性、性能、故障影響和異構技術,對於每種驅動力,他都給出了樣例以及該驅動力對不同類型架構的影響。

Grzybek最後強調:

系統架構的形狀會受到各種因素的影響,一切都取決於我們所處的環境。

去年年底,Grzybek發布了一個開源項目,在該項目中,他詳細闡述瞭如何使用領域驅動設計(Domain-Driven Design,DDD)的方式去設計、實現單體應用。他的目標是通過這個項目展示如何以模塊化的方式設計和實現單體應用。

在柏林舉行的microXchg 2019年會議上,Jan de Vries主張在使用微服務之前先構建一個單體

在Reactive Summit 2018會議上,Randy Shoup在演講中描述了以增量式架構方式構建系統,他表示系統應該從簡單的架構開始,並隨著需求的增加而不斷演化。

在2015年的一篇博客文章中,Stefan Tilkov認為微服務的主要好處是在系統的不同部分之間創建了清晰且嚴格的邊界。他反對微服務體系結構始終應該從單體開始的觀點,他認為先構建具有清晰分割的結構良好的單體應用,隨後再將其轉換成微服務是極其困難的,甚至根本不可能。

原文鏈接:

Modular Monolithic Architecture, Microservices and Architectural Drivers