對比:微服務VS單體架構

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"越來越多的組織開始放棄單體應用,逐步轉向微服務的架構模式–將業務流程分爲多個獨立的服務。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如,在一個機票預訂中,就可能涉及許多個單獨的過程:在航空公司預訂機票,付款,並在機票成功預訂後向客戶發送確認信息。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"微服務架構,就是將","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"各個流程按照業務拆分爲獨立的服務","attrs":{}},{"type":"text","text":"。在上面的示例中,機票預訂服務可以被拆分爲機票預訂,付款和確認,拆分後的微服務可以通過接口相互通信。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,微服務與單體應用,究竟有什麼不同?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比1:網絡延遲","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當涉及微服務時,有一個基本的物理定律在起作用,每當微服務通過網絡調用另一服務時,字節就通過網絡發送,這涉及將字節轉換爲電信號或脈衝光,然後將這些信號轉換回字節。根據模擬結果,微服務調用的等待時間至少爲24ms。如果我們假設實際處理大約需要100毫秒,則總處理時間如下所示:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/71/713198485c6ee1ba6a5ac82223ec5e06.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"網絡延遲-微服務與單體應用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"假設在理想情況下,所有調用執行可以同時發生,並且彼此之間不依賴–這稱爲扇出模式( fan-out pattern)。下圖顯示了隨着越來越多的調用同時執行,總時間如何減少。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d6/d6a2fba2606baaf55c7b3ce934ca4345.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同時執行多個調用意味着總執行時間減少","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"並行執行所有調用,意味着最長的調用執行完,服務將返回給使用者。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從上圖可以看出,單體應用沒有網絡延遲,因爲所有調用都是本地調用。即使在完全可並行化的世界中,單體應用仍會更快。而微服務由於需要多個服務間通信,即使並行調用,也是需要一定的網絡延遲。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這一次,單體應用勝利了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比2:複雜性","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"考慮複雜性時,有許多因素在起作用:開發的複雜性和運行軟件的複雜性。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於開發的複雜性,在構建基於微服務的軟件時,代碼庫的大小會快速增長。因爲微服務涉及多個源代碼,使用不同的框架甚至不同的語言。由於微服務需要彼此獨立,因此經常會有代碼重複。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外,由於開發和發佈時間不一致,因此不同的服務可能會使用不同版本的庫。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於日誌和監控方面,在單體應用中,日誌記錄就像查看單個日誌文件一樣簡單。但是,對於微服務,跟蹤問題可能涉及檢查多個日誌文件。不僅需要查找所有相關的日誌輸出,而且還需要以正確的順序將它們放在一起。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Kubernetes集羣中運行微服務時,複雜度進一步增加。雖然Kubernetes啓用了諸如彈性伸縮等功能,但它並不是一個易於管理的系統。要部署單體應用,簡單的複製操作就足夠了。要啓動或停止單體應用,通常只需一個簡單的命令即可。還有與單體應用相比,事務還增加了運行微服務架構的複雜性。跨服務的調用,很難保證數據是同步的。例如,執行不當的調用,重試可能會執行兩次付款。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這一次,單體應用又勝利了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比3:可靠性","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在微服務中,如果A服務通過網絡以99.9%的可靠性調用B服務(這意味着在1000個調用中,有一個將由於網絡問題而失敗),這時B調用再C服務,我們將獲得99.8%的可靠性。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6c/6c5472cab7caa2a542e6a5249577e9fa.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着調用時間的延長,可靠性下降","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,在設計微服務架構時,要考慮網絡會在某個時刻斷開。微服務提供了一些解決此問題的解決方案。Spring Cloud提供了負載均衡和網絡故障處理,諸如Istio之類的服務網格還能夠處理多種編程語言的服務。當微服務集羣中的服務失敗時,集羣管理器給出替代方案。這就使得微服務架構具有高度的彈性。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Netflix創建了一個名爲Chaos Monkey的工具,該工具可以模擬隨機終止虛擬機和容器。微服務的開發者,可以使用Chaos Monkey的工具在測試環境模擬網絡斷連和網絡故障等問題,這樣,他們就可以確保系統能夠處理生產環境中的停機故障。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單體應用中的所有調用都是在本地完成,因此很少發生網絡故障,雖然如此,然而單體應用在雲環境卻無法滿足彈性伸縮的需求。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,微服務取得了勝利。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比4:資源使用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般來說,微服務會比單體應用使用更多的資源。即使在Docker中運行時,基準測試發現,雖然服務連接數量下降了8%,但是容器編排還將消耗資源,日誌聚合和監視也將消耗資源。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,微服務使我們可以更聰明地使用資源。由於集羣管理器可以根據需要分配資源,因此實際的資源使用量可能要低得多。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在軟件中,20%的代碼一般會完成80%的工作。如果單體應用的一個實例使用8GB,則兩個實例使用16GB,依此類推。使用微服務後,我們可以把單體應用中負責主要職能的20%代碼提取成一個服務,因此對於兩個實例,我們的RAM使用量爲降低到了9.6GB左右。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下圖顯示了資源使用情況的差異。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fa/fa47247db2461f94f0f70b72f8fd2cea.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着越來越多的實例在運行,單體應用比微服務需要更多的資源","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"資源使用率方面,微服務勝利了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比5:擴展的精確性","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單體應用的擴展有多種辦法,運行多個實例,或運行多個線程,或者使用非阻塞IO。對於微服務架構,這三個也都是適用的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,面對客戶端越來越多的請求,由於微服務架構更精細,因此擴展單個服務也更加精細。所以,對於微服務來說,擴展既簡單又精確。而且,由於微服務的資源消耗較少,又可以節省資源。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/00bfd8b4fdda316a9b69fcac4f30b873.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相比單體應用,微服務精確的擴展和更少的資源使用,是一個明顯的勝利。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比6:吞吐量","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓我們再看一個性能指標–吞吐量。在微服務架構體系中,數據需要在不同服務之間發送,從而會產生一定的開銷。如果微服務還不是一個分佈式架構,那麼他的吞吐量還不如一個單體應用高。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比7:部署時間","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"人們選擇微服務架構的原因之一就是-能夠節省部署時間,滿足快速迭代。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於微服務的職責單一原則,因此對其進行的任何更改都有很明確。然而,修改一個單體應用的功能,可能會“牽一髮動全身”。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此外,微服務更易於測試。由於微服務僅覆蓋有限的一組功能,因此代碼依賴性低,便於編寫測試並且運行得快。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還有,微服務的資源消耗較少,並且可以按比例擴展。這就使微服務可以無感知部署,例如,可以先在集羣一部分節點上啓動微服務的新版本,然後遷移一部分用戶到新版本,如果有問題,這可以快速回滾到舊版本。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"勝利歸功於微服務。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對比8:溝通","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在微服務誕生之前,弗雷德·布魯克斯(Fred Brooks)撰寫了開創性的著作《人月神話》,本書的其中一項內容是,溝通渠道的數量隨着團隊成員的數量而增加。由兩個人組成的團隊,只有一個溝通渠道。如果有四個人,則最多可以訪問六個頻道。通信通道數的公式爲n(n − 1)/2。由20位開發人員組成的團隊擁有190個可能的溝通渠道。將這些開發人員分成兩個團隊,就可以大大減少溝通渠道的數量。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們以擁有20個開發人員的團隊爲例,將其分爲四個微服務團隊(每個團隊五個人),則每個團隊有10個溝通渠道。四個團隊之間的溝通渠道只有六個。溝通渠道的總數爲46,大約佔20個人團隊的四分之一。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下圖顯示了,一個大團隊的通信渠道數量,和單個微服務團隊的通信渠道數量的對比。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/aa/aafca7c4cd8d3772e09d68df1b7938f8.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,將10個以上的開發人員分成幾個較小的團隊,可以爲任何開發項目提供更高的溝通效率。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是微服務的另一個明顯勝利。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"誰是贏家?","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e0/e08dbeea3bced32f9aec44139e932b38.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單體應用獲得了3場勝利,微服務獲得了5場勝利。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,在查看此圖表時,請記住它是相對的。微服務並不是解決所有開發問題的萬能藥。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如,一個由5個開發人員組成的小型團隊可能會傾向於選擇單體應用。因爲,單體應用不僅更易於管理,同時如果軟件產品每秒僅有幾個訪問量,那麼單體應用可能就足夠了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以下是一些跡象,表明微服務架構可能是一個合適的選擇:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要7*24的可靠性","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"精確的擴展","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"峯值和正常負載明顯不同","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"超過10個開發人員的團隊","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務領域可以被細分","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方法調用鏈路短","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方法調用可以使用REST API或隊列事件。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"幾乎沒有跨服務的事務","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章