來源:https://thenewstack.io/microservices-vs-monoliths-an-operational-comparison/java
愈來愈多的組織開始放棄單體應用,逐步轉向微服務的架構模式–將業務流程分爲多個獨立的服務。web
例如,在一個機票預訂中,就可能涉及許多個單獨的過程:在航空公司預訂機票,付款,並在機票成功預訂後向客戶發送確認信息。編程
微服務架構,就是將各個流程按照業務拆分爲獨立的服務。在上面的示例中,機票預訂服務能夠被拆分爲機票預訂,付款和確認,拆分後的微服務能夠經過接口相互通訊。微信
那麼,微服務與單體應用,究竟有什麼不一樣?網絡
對比1:網絡延遲
當涉及微服務時,有一個基本的物理定律在起做用,每當微服務經過網絡調用另外一服務時,字節就經過網絡發送,這涉及將字節轉換爲電信號或脈衝光,而後將這些信號轉換回字節。根據模擬結果,微服務調用的等待時間至少爲24ms。若是咱們假設實際處理大約須要100毫秒,則總處理時間以下所示:架構
![](http://static.javashuo.com/static/loading.gif)
網絡延遲-微服務與單體應用app
假設在理想狀況下,全部調用執行能夠同時發生,而且彼此之間不依賴–這稱爲扇出模式( fan-out pattern)。下圖顯示了隨着愈來愈多的調用同時執行,總時間如何減小。負載均衡
![](http://static.javashuo.com/static/loading.gif)
同時執行多個調用意味着總執行時間減小框架
並行執行全部調用,意味着最長的調用執行完,服務將返回給使用者。編程語言
從上圖能夠看出,單體應用沒有網絡延遲,由於全部調用都是本地調用。即便在徹底可並行化的世界中,單體應用仍會更快。而微服務因爲須要多個服務間通訊,即便並行調用,也是須要必定的網絡延遲。
這一次,單體應用勝利了。
對比2:複雜性
考慮複雜性時,有許多因素在起做用:開發的複雜性和運行軟件的複雜性。
因爲開發的複雜性,在構建基於微服務的軟件時,代碼庫的大小會快速增加。由於微服務涉及多個源代碼,使用不一樣的框架甚至不一樣的語言。因爲微服務須要彼此獨立,所以常常會有代碼重複。
另外,因爲開發和發佈時間不一致,所以不一樣的服務可能會使用不一樣版本的庫。
對於日誌和監控方面,在單體應用中,日誌記錄就像查看單個日誌文件同樣簡單。可是,對於微服務,跟蹤問題可能涉及檢查多個日誌文件。不只須要查找全部相關的日誌輸出,並且還須要以正確的順序將它們放在一塊兒。
在Kubernetes集羣中運行微服務時,複雜度進一步增長。雖然Kubernetes啓用了諸如彈性伸縮等功能,但它並非一個易於管理的系統。要部署單體應用,簡單的複製操做就足夠了。要啓動或中止單體應用,一般只需一個簡單的命令便可。還有與單體應用相比,事務還增長了運行微服務架構的複雜性。跨服務的調用,很難保證數據是同步的。例如,執行不當的調用,重試可能會執行兩次付款。
這一次,單體應用又勝利了。
對比3:可靠性
在微服務中,若是A服務經過網絡以99.9%的可靠性調用B服務(這意味着在1000個調用中,有一個將因爲網絡問題而失敗),這時B調用再C服務,咱們將得到99.8%的可靠性。
![](http://static.javashuo.com/static/loading.gif)
隨着調用時間的延長,可靠性降低
所以,在設計微服務架構時,要考慮網絡會在某個時刻斷開。微服務提供了一些解決此問題的解決方案。Spring Cloud提供了負載均衡和網絡故障處理,諸如Istio之類的服務網格還可以處理多種編程語言的服務。當微服務集羣中的服務失敗時,集羣管理器給出替代方案。這就使得微服務架構具備高度的彈性。
Netflix建立了一個名爲Chaos Monkey的工具,該工具能夠模擬隨機終止虛擬機和容器。微服務的開發者,可使用Chaos Monkey的工具在測試環境模擬網絡斷連和網絡故障等問題,這樣,他們就能夠確保系統可以處理生產環境中的停機故障。
單體應用中的全部調用都是在本地完成,所以不多發生網絡故障,雖然如此,然而單體應用在雲環境卻沒法知足彈性伸縮的需求。
最後,微服務取得了勝利。
對比4:資源使用
通常來講,微服務會比單體應用使用更多的資源。即便在Docker中運行時,基準測試發現,雖然服務鏈接數量降低了8%,可是容器編排還將消耗資源,日誌聚合和監視也將消耗資源。
可是,微服務使咱們能夠更聰明地使用資源。因爲集羣管理器能夠根據須要分配資源,所以實際的資源使用量可能要低得多。
在軟件中,20%的代碼通常會完成80%的工做。若是單體應用的一個實例使用8GB,則兩個實例使用16GB,依此類推。使用微服務後,咱們能夠把單體應用中負責主要職能的20%代碼提取成一個服務,所以對於兩個實例,咱們的RAM使用量爲下降到了9.6GB左右。
下圖顯示了資源使用狀況的差別。
![](http://static.javashuo.com/static/loading.gif)
隨着愈來愈多的實例在運行,單體應用比微服務須要更多的資源
資源使用率方面,微服務勝利了。
對比5:擴展的精確性
單體應用的擴展有多種辦法,運行多個實例,或運行多個線程,或者使用非阻塞IO。對於微服務架構,這三個也都是適用的。
可是,面對客戶端愈來愈多的請求,因爲微服務架構更精細,所以擴展單個服務也更加精細。因此,對於微服務來講,擴展既簡單又精確。並且,因爲微服務的資源消耗較少,又能夠節省資源。
![](http://static.javashuo.com/static/loading.gif)
相比單體應用,微服務精確的擴展和更少的資源使用,是一個明顯的勝利。
對比6:吞吐量
讓咱們再看一個性能指標–吞吐量。在微服務架構體系中,數據須要在不一樣服務之間發送,從而會產生必定的開銷。若是微服務還不是一個分佈式架構,那麼他的吞吐量還不如一個單體應用高。
對比7:部署時間
人們選擇微服務架構的緣由之一就是-可以節省部署時間,知足快速迭代。
因爲微服務的職責單一原則,所以對其進行的任何更改都有很明確。然而,修改一個單體應用的功能,可能會「牽一髮動全身」。
此外,微服務更易於測試。因爲微服務僅覆蓋有限的一組功能,所以代碼依賴性低,便於編寫測試而且運行得快。
還有,微服務的資源消耗較少,而且能夠按比例擴展。這就使微服務能夠無感知部署,例如,能夠先在集羣一部分節點上啓動微服務的新版本,而後遷移一部分用戶到新版本,若是有問題,這能夠快速回滾到舊版本。
勝利歸功於微服務。
對比8:溝通
在微服務誕生以前,弗雷德·布魯克斯(Fred Brooks)撰寫了開創性的著做《人月神話》,本書的其中一項內容是,溝通渠道的數量隨着團隊成員的數量而增長。由兩我的組成的團隊,只有一個溝通渠道。若是有四我的,則最多能夠訪問六個頻道。通訊通道數的公式爲n(n − 1)/2。由20位開發人員組成的團隊擁有190個可能的溝通渠道。將這些開發人員分紅兩個團隊,就能夠大大減小溝通渠道的數量。
咱們以擁有20個開發人員的團隊爲例,將其分爲四個微服務團隊(每一個團隊五我的),則每一個團隊有10個溝通渠道。四個團隊之間的溝通渠道只有六個。溝通渠道的總數爲46,大約佔20我的團隊的四分之一。
下圖顯示了,一個大團隊的通訊渠道數量,和單個微服務團隊的通訊渠道數量的對比。
![](http://static.javashuo.com/static/loading.gif)
所以,將10個以上的開發人員分紅幾個較小的團隊,能夠爲任何開發項目提供更高的溝通效率。
這是微服務的另外一個明顯勝利。
誰是贏家?
![](http://static.javashuo.com/static/loading.gif)
單體應用得到了3場勝利,微服務得到了5場勝利。
可是,在查看此圖表時,請記住它是相對的。微服務並非解決全部開發問題的萬能藥。
例如,一個由5個開發人員組成的小型團隊可能會傾向於選擇單體應用。由於,單體應用不只更易於管理,同時若是軟件產品每秒僅有幾個訪問量,那麼單體應用可能就足夠了。
如下是一些跡象,代表微服務架構多是一個合適的選擇:
-
須要7*24的可靠性 -
精確的擴展 -
峯值和正常負載明顯不一樣 -
超過10個開發人員的團隊 -
業務領域能夠被細分 -
方法調用鏈路短 -
方法調用可使用REST API或隊列事件。 -
幾乎沒有跨服務的事務
本文分享自微信公衆號 - 肥朝(feichao_java)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。