[譯] 模塊化 vs. 微服務

模塊化 vs. 微服務

使用模塊化系統設計原則來避免微服務的複雜性。html

從單體式應用向微服務架構遷移已是老生常談的話題了。除了過過嘴癮,彷佛真的動手將單體式應用拆分紅微服務也不是什麼很困難的事。可是這種作法真的是大家團隊的最佳選擇嗎?維護一個凌亂的單體式應用的確很傷腦筋,可是還有另外一種優秀但經常被人忽視的替代方案:模塊化應用開發。本文將探討這種替代方案,並展示其與構建微服務的關係。前端

模塊化微服務

「經過微服務,咱們終於可以讓團隊獨立工做了」或者「咱們的單體式應用實在太複雜了,它下降了咱們的工做效率」之類的話,只是讓團隊改用微服務架構的諸多緣由中的一小部分;還有一種說法是須要可拓展性與彈性。全部開發人員彷佛都渴望系統設計和開發的模塊化。軟件開發中的模塊化能夠總結爲如下三個原則:java

  • 強大的封裝性:隱藏了各個組件內部實現的細節,減小了不一樣組件之間的耦合性。團隊能夠在系統的各個非耦合部分中獨立地工做。
  • 定義良好的接口:你不可能隱藏組件內的全部東西(不然你的系統將毫無心義),所以有必要在組件之間定義良好且可靠的 API。任意一個組件均可以被符合接口規範的其它組件替換。
  • 顯式依賴:模塊化系統意味着不一樣的組件須要在一塊兒工做。所以你最好能有一種途徑來表達(與驗證)它們之間關係。

這些原則均可以用微服務架構來實現。只要作到對其它服務暴露定義明確的接口(一般是一個 REST API),就能以任意方式來實現一個微服務。它的實現細節是這個服務內部的事情,你能夠改變這些實現細節而不影響整個系統。微服務之間的依賴關係一般在開發時是不明確的,這可能會致使在運行時服務編排失敗。只能說在大多數微服務架構中,實現最後一條模塊化原則還須要再接再礪。react

所以,微服務架構實現了重要的模塊化原則,並帶來了如下三點實實在在的好處:android

  • 團隊可以獨立地工做與擴張。
  • 微服務小巧、專注,下降了複雜度。
  • 服務能夠在不會影響全局的狀況下內部進行更改或者替換。

那麼微服務架構的缺點是什麼呢?當你從一個單體式(雖然有點臃腫)應用切換成微服務分佈式系統的時候,給表操做帶來了巨大的複雜性。忽然間,你發現你要不斷地部署各類不一樣的(多是由容器包裝的)服務。這時,服務發現、分佈式日誌記錄、跟蹤等新的問題出現了。如今,你更加容易出現分佈式計算的謬論形成的錯誤。接口的版本管理與配置管理成爲你面對的主要問題。各類問題將數不勝數向你涌來。ios

事實證實,因爲全部的微服務個體都須要聯合起來實現業務邏輯,微服務之間的鏈接將變得無比複雜。看到這裏,你應該意識到不能簡單地將單體式應用拆分紅微服務了。單體式應用中的「意大利麪條式代碼」問題重重,在其中再加上網絡邊界會將這些糾纏在一塊兒的問題升級成徹頭徹尾的痛苦。git

模塊化的替代方案

這是否意味着咱們要麼沉沒在混亂的單體式應用中,要麼淹沒在使人抓狂的微服務複雜性中呢?其實,模塊化也能夠經過其它方式實現。在開發時最重要的是正確地規劃項目邊界並實施方案,咱們也能夠經過建立一個結構良好的單體式應用來實現這一點。固然,這意味着咱們將盡量利用編程語言與開發工具的協助來實現模塊化原則。es6

例如在 Java 中,有幾個能夠幫助你構建應用的模塊系統。OSGi 是其中最著名的一個,不過隨着 Java 9 的發佈,Java 平臺將加入一個原生的模塊系統。如今模塊做爲一等結構(first-class construct),成爲了語言和平臺的一部分。Java 模塊能夠代表對其它模塊的依賴,以及在強封裝實現類的時候公開暴露接口。甚至 Java 平臺自己(一個龐大的代碼庫)已經使用了新的 Java 模塊系統進行模塊化。你能夠在我即將出版的書Java 9 Modularity中瞭解有關 Java 9 模塊化開發的更多信息。(現早期版本已經發布)github

其它的語言也提供了相似的機制。例如,JavaScript 在 ES2015 規範中提供了一個模塊系統。在此以前,Node.js 也爲 JavaScript 後端提供了一個非標準的模塊系統。然而 JavaScript 做爲一種動態語言,對於強制接口(類型)與模塊封裝的支持仍是較弱。你能夠考慮在 JavaScript 的基礎上使用 TypeScript 來從新得到這些優勢。微軟的 .Net 框架與 Java 同樣都有着強類型,但就強封裝以及程序集(Assemblies)間的顯式依賴而言,它與 Java 即將推出的模塊系統並不相同。儘管如此,你能夠經過使用 .Net Core 中標準化的反轉控制模式(IOC)以及建立邏輯相關的程序集來實現良好的模塊化架構。即便是 C++ 也在之後的版本中考慮添加模塊系統。許多語言都在向模塊化靠近,這自己就是一個顯著的進步。數據庫

當你有意識地使用你的開發平臺的模塊化特性時,你就能夠實現以前說起的微服務的模塊化優點。基本上模塊系統越好,你在開發過程當中得到的幫助就越多。只要在不一樣團隊間的接觸點定義好明確的接口,不一樣的團隊也能夠獨立進行不一樣部分的工做。固然,在部署時仍是要將模塊在一個單獨的部署單元中組合起來。這樣能夠防止過於複雜,以及減小遷移到微服務所須要的開發與管理成本。誠然,這也意味着你不能使用不一樣的技術棧來構建不一樣的模塊,但你的團隊應該不會真的這麼作吧?

模塊設計

建立好的模塊和建立好的微服務同樣,都須要嚴謹的設計。一個模塊應該基於其域的有界上下文建模(DDD)。選擇微服務的邊界是架構上重要的決策,一旦出錯就可能要付出沉重的代價。相較而言,模塊化應用程序模塊的邊界更容易修改一些。模塊間的重構一般由類型系統和編譯器支持。微服務邊界的從新劃分則涉及大量的進程間通訊(IPC),以確保運行時穩定性。老實說,你真的只用一次兩次就能正確的劃分好邊界?

在許多方面,靜態語言的模塊爲了定義明確的接口而提供了更好的結構。經過調用另外一個模塊暴露的接口提供的方法,比去調用另外一個微服務的 REST 端點健壯性要強的多。REST+JSON 如今無處不在,但在沒有編譯器檢查的狀況下,它並無」類型良好的互通性「這個特色。而事實上,經過網絡序列化(或者反序列化)數據並非無開銷的,甚至這種傳輸方式更加遜色。此外,許多模塊化系統容許你代表此模塊對於其它模塊的依賴關係,模塊系統將不容許違背這些依賴關係的狀況出現。而微服務之間的依賴關係只在運行時實現,致使系統難以調試。

模塊也是代碼全部權中的天然單位。一個團隊能夠負責系統中的一個或者多個模塊,而只須要給其它團隊提供模塊的公共 API。在運行時,模塊之間的隔離比微服務少,畢竟模塊化單體式應用的全部模塊都運行在同一個進程中。

毫無疑問,單體式應用的模塊不可能像微服務同樣有本身的數據。模塊化應用內部的數據交流是經過定義良好的接口或者模塊間的消息進行的,而不是經過共享數據存儲進行。它與微服務最大的差異就是它的一切都發生在同一個進程中,所以一樣不能低估最終的數據一致性問題。對於模塊來講,最終的一致性問題能夠是一個策略問題,或者你也能夠僅將數據」邏輯地「分開存儲在同一數據庫內並仍然使用跨域事務。而對於微服務來講,這個問題別無選擇:必須保證最終的一致性。

什麼時候微服務才適用於你的團隊?

那麼什麼時候遷移到微服務架構才合適呢?到目前爲止,咱們主要關注的是如何經過模塊化來解決複雜性問題。對於這一點,微服務與模塊化應用均可以作到,只不過各有所難。

當你的團隊有如同 Google 或者 Netflix 般的規模的時候,擁抱微服務是毋庸置疑的。你有能力去創建你本身的平臺與工具庫,而且工程師的數量排除了任何使用單體式解決方案的可能。可是大多數的組織都達不到這個規模。即便你認爲你的公司有朝一日將成爲一個市值十億美圓的獨角獸,在剛起步時使用模塊化的單體式應用也無傷大雅。

另外一個拆分微服務的理由是:不一樣的服務在實現上更適合使用不一樣的技術棧。那麼,你必須有足夠的規模來吸引人才以解決這些迥然不一樣的技術棧,並支持這些平臺的運行。

微服務還能夠作到獨立部署系統的不一樣部分,這在大多數模塊化平臺中很難(甚至不可能)實現。隔離部署增長了系統的彈性與容錯能力。此外,每一個微服務的縮放特性能夠是不一樣的,能夠部署不一樣的微服務以匹配硬件。模塊化的單體式應用能夠進行水平縮放,可是隻能將全部模塊捆綁在一塊兒同時進行拓展。雖然你能夠經過這種方法獲得不少好處,但這可能並非最好的解決方案。

總結

總之,最好的方案就是找到一個折中的點。這兩種方案都有可取之處,須要根據實際環境、組織和應用自己進行選擇。既然你能夠在以後遷移成微服務架構,那爲何最開始不直接使用模塊化應用呢?若是你以前就已經劃分好了模塊邊界,那也就不須要再去拆分你的單體式應用了。甚至你還能夠在模塊內部搭建微服務架構。那麼問題就變成了:爲何微服務必定要是「微」的呢?

即便你的應用剛從模塊化應用轉成微服務架構,服務也沒必要非得很「微」才具有可維護性。在服務中應用模塊化原則能讓它們在複雜度的可擴展性上超越一般的微服務。如今這份藍圖中既有微服務也有模塊,減小架構中的服務的數量能夠節約成本;而其中的模塊能夠像構建單體式應用同樣,構建和擴展服務。

若是你追求模塊化的好處,請確保本身不要自嗨進入一種「非微服務不可」的心態。探索你喜好的技術棧中的同進程模塊化功能或框架,你將會獲得支持去真正的執行模塊化設計,而不是僅靠着約定來避免「意大利麪條式代碼」。最後,請深思熟慮後再選擇:你是否願意接受引入微服務形成的複雜度成本。有的時候你別無選擇,但更多的時候其實你能夠找到更好的解決方案。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃

相關文章
相關標籤/搜索