微服務的好處(優點)有哪些?

顯然,隨着系統複雜度的提升,以及對系統擴展性的要求越來越高,微服務化是一個很好的方向,但除此之外,微服務還會給我們帶來哪些好處?

獨立,獨立,還是獨立

我們說微服務打響的是各自的獨立戰爭,所以,每一個微服務都是一個小王國,這些微服務跳出了“大一統”(Monolith)王國的統治,開始從各個層面打造自己的獨立能力,從而保障自己的小王國可以持續穩固的運轉。

首先,在開發層面,每個微服務基本上都是各自獨立的項目(project),而對應各自獨立項目的研發團隊基本上也是獨立對應,這樣的結構保證了微服務的並行研發,並且各自快速迭代,不會因爲所有研發都投入一個近乎單點的項目,從而造成開發階段的瓶頸。開發階段的獨立,保證了微服務的研發可以高效進行。

服務開發期間的形態,跟服務交付期間的形態原則上是不需要完全高度統一的,即使我們在開發的時候都是各自進行,但交付的時候還是可以一起交付,不過這不是微服務的做法。

在微服務治理體系下,各個微服務交付期間也是各自獨立交付的,從而使得每個微服務從開發到交付整條鏈路上都是獨立進行,這大大加快了微服務的迭代和交付效率。

服務交付之後需要部署運行,對微服務來說,它們運行期間也是各自獨立的。

微服務獨立運行可以帶來兩個比較明顯的好處,第一個就是可擴展性。我們可以快速地添加服務集羣的實例,提升整個微服務集羣的服務能力,而在傳統 Monolith 模式下,爲了能夠提升服務能力,很多時候必須強化和擴展單一結點的服務能力來達成。如果單結點服務能力已經擴展到了極限,再尋求擴展的話,就得從軟件到硬件整體進行重構。

軟件行業有句話:“Threads don't scale,Processes do!”,很明確地道出了原來 Monolith 服務與微服務在擴展(Scale)層面的差異。

對於 Java 開發者來說,早些年(當然現在也依然存在),我們遵循 Java EE 規範開發的 Web 應用,都需要以 WAR 包的形式部署到 TOMCAT、Jetty、RESIN 等 Web 容器中運行,即使每個 WAR 包提供的都是獨立的微服務,但因爲它們都是統一部署運行在一個 Web 容器中,所以擴展能力受限於 Web 容器作爲一個進程(process)的現狀。

無論如何調整 Web 容器內部實現的線程(thread)設置,還是會受限於 Web 容器整體的擴展能力。所以,現在很多情況下,大家都是一個 TOMCAT 只部署一個 WAR,然後通過複製和擴展多個 TOMCAT 實例來擴展整個應用服務集羣。

當然,說到在 TOMCAT 實例中只部署一個 WAR 包這樣的做法,實際上不單單只是因爲擴展的因素,還涉及微服務運行期間給我們帶來的第二個好處,即隔離性。

隔離性實際上是可擴展性的基礎,當我們將每個微服務都隔離爲獨立的運行單元之後,任何一個或者多個微服務的失敗都將隻影響自己或者少量其他微服務,而不會大面積地波及整個服務運行體系。

在架構設計上有一種實踐模式,即隔板模式(Bulkhead Pattern),這種架構設計模式的首要目的就是爲了隔離系統中的各個功能單元和實體,使得系統不會因爲一個單元或者服務的失敗而導致整體失敗。

這種思路在造船行業、兵工行業都有類似的應用場景。現在任何大型船舶在設計上都會有隔艙,目的就是即使有少量進水,也可以只將進水部位隔離在小範圍,不會擴散而導致船舶大面積進水,從而沉沒。當年泰坦尼克號雖然沉了,但不意味着他們沒有做隔艙設計,只能說,傷害度已經遠遠超出隔艙可以提供的基礎保障範圍。

在坦克的設計上,現在一般也會將彈藥艙和乘員艙隔離,從而可以保障當坦克受創之後,將傷害儘量限定在指定區域,儘量減少對車乘成員的傷害。

前面我們提到,現在大家基本上弱化了 Java EE 的 Web 容器早期採用的“一個 Web 容器部署多個 WAR 包”的做法,轉而使用“一個 Web 容器只部署一個 WAR 包”的做法,這實際上正是綜合考慮了 Web 容器的設計和實現現狀與真實需求之後做出的合理實踐選擇。

這些 Web 容器內部大多通過類加載器(Classloader)以及線程來實現一定程度上的依賴和功能隔離,但這些機制從基因上決定了這些做法不是最好的隔離手段。而進程(Process)擁有天然的隔離特性,所以,一個 WAR 包只部署運行在一個 Web 容器進程中才是最好的隔離方式。

現在回想一下,好像自從各個微服務打響獨立戰爭並且獨立之後,無論從哪個層面來看,各自“活”得都挺好。































多語言生態

微服務獨立之後,給了對應的團隊和組織快速迭代和交付的能力,同時,也給團隊和組織帶來了更多的靈活性,實際上,對應交付不同微服務的團隊或者組織來說,現在可以基於不同的計算機語言生態構建這些微服務,如圖 1 所示。

微服務的提供者既可以使用 Java 或者 Go 等靜態語言完成微服務的開發和交付,也可以使用 Python 或者 Ruby 等動態語言完成微服務的開發和交付,對於團隊內部擁有繁榮且有差異的語言文化來說,多語言生態下的微服務開發和交付將可以最大化的發揮團隊和組織內部各成員的優勢。

當然,對於多語言生態下的微服務研發來說,有一點需要注意:爲了讓服務的訪問者可以用統一的接口訪問所有這些用不同語言開發和交互的微服務,應該儘量統一微服務的服務接口和協議。

在微服務的生態下,互通性應該是需要重點關注的因素,沒有互通,不但服務的訪問者和用戶無法很好地使用這些微服務,微服務和微服務之間也無法相互信賴和互助,這將大大損耗微服務研發體系帶來的諸多好處,而多語言生態也會變成一種障礙和負累,而不是益處。

記得時任黑貓宅急便社長的小倉昌男在其所著的《黑貓宅急便的經營學》中提到一個故事,日本國鐵曾經採用不同於國際標準的集裝箱和鐵路規格,然後發現貨物的運輸效率很低,經過考察發現,原來是貨物從國際標準集裝箱卸載之後,在通過日本國鐵運輸之前,需要先拆箱,重新裝入日本國鐵規格的集裝箱,然後裝載到日本國鐵上進行運輸。

但是,如果日本國鐵採用國際標準的集裝箱規格,那麼貨物集裝箱從遠洋輪船上卸載之後就可以直接裝上國鐵,這將大大加快運輸效率(日本,國鐵改革後也證明確實如此)。日本國鐵在前期採用私有方案時,只關注了自己的利益和效率,捨棄了互通,也帶來了效率的低下。

所以,在開發和交付微服務的時候,尤其是在多語言生態下開發和交付微服務,我們從一開始就要將互通性作爲首要考慮因素,從而不會因爲執迷於某些服務或者系統的單點效率而失去了整個微服務體系的整體效率。












圖片
圖 1  多語言的微服務生態



圖片


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章