一文讀懂微服務與服務網格——「WHAT, WHY and HOW TO DO」

做者注:
聯繫方式 leontian1024@gmail.com || github.com/XinyaoTian
新人入行,很是期待能與各位大牛們討論,感謝各位的閱讀,但願對您有所幫助。

一切都要從雲計算和容器技術的出現提及...

相信每一位老道的開發者和軟件工程師們都會有過,曾經( 也許如今仍然 )被龐大且複雜的軟件系統所支配的恐懼。隨着軟件版本的迭代和開發團隊人員規模的擴大,曾經那個小巧別緻、設計精良的軟件或應用一去不返,現在已經變得遍地狼藉,慘不忍睹——混亂的接口、不規範的調用、像貼狗皮膏藥通常貼上去的新功能組件……曾經那個賞心悅目的應用,現在看了就反胃。這一切都預示着一個問題:開發軟件的方式須要改變。git

縱使有那麼多種軟件開發模式,但若是不能從底層技術上實現對設計的約束,問題將會隨着時間的推移,最終暴露出來。譬如「高內聚,低耦合」的設計理念,若是不能從底層就實現模塊間的隔離,而依靠開發時的技巧和經驗,那麼最終這個軟件依舊會變得一團糟( 由於團隊會有新人的加入、即便經驗老道的開發者也會有頭腦發昏的時候…… )。所以,「不這麼寫就沒法運行」這樣的硬性要求就頗有必要了。github

雲計算和容器技術的出現,很是及時地幫助咱們解決了這一難題。雲計算的高彈性和按需分配、容器技術的快速啓停和隔離,都很好的幫助了咱們減小運維開銷,且對於不一樣模塊實現操做系統級別的隔離。在這兩種關鍵技術出現先後,軟件架構的差異以下圖所示:
圖片描述docker

( 上圖: 單體應用 與 微服務應用 )

以 Web 應用爲例,按照以前的開發方式,咱們每每會選用一個功能齊全但至關複雜的開發框架( 好比JAVA開發經常使用的 SpringBoot ),而後在這個框架的基礎上,根據開發經驗和框架的功能將整個應用分層( 好比最經常使用的表示層、業務邏輯層和數據資源層的分層方法 ),以後根據需求分析得出的各個功能,經過不一樣目錄、文件和函數的方式分別開發,最終一個完整的 Web 應用被開發出來。其過程以下圖所示。
圖片描述數據庫

( 上圖: 基於框架的軟件開發架構網格 )

經過使用框架,咱們把軟件在層次上分爲三層,而以後的每一個功能,就至關於縱向地添加一個新列。若是以這種方式看待一個應用,那麼咱們就能夠將任何基於這種開發方法的應用看做一個3行n列的表格或矩陣了。編程

然而,這種很是普及的開發方式仍然有一些問題...

雖然這種開發方式已經很是普及,很是成熟,但其仍有許多有待改進的地方。好比:網絡

依賴和庫過於龐雜。理想狀況下,咱們但願針對每個模塊,單獨管理其相應的依賴和庫,而不是以整個應用做爲單位來管理。架構

沒法改變層次結構。某種層次結構對於某些業務需求來講很棒,但對於另一些也許就顯得不那麼合適了。使用這種方式開發,幾乎全部功能都要聽從這種既定的層次開發( 好比寫 UI、寫業務邏輯、寫數據庫層 )。而對於目前日漸快速的迭代和敏捷的開發思想,咱們須要一種更加靈活輕便的方式進行開發。app

沒法實現跨語言開發。咱們知道,幾乎每種編程語言都有本身最擅長的領域。也許某些功能選用其餘編程語言的開發效率更高,運行效果更好。然而,使用這種方式咱們每每只能使用選定的框架所支持的語言。負載均衡

模塊的獨立性不足。單純經過函數和文件來進行隔離,隔離性仍然不夠。一個疏忽或是加急上線就會讓以前良好的高內聚低耦合的良好軟件結構灰飛煙滅。所以,咱們須要更加底層的機制來硬性約束咱們實現「高內聚低耦合」,把「應該這麼作」變爲「必須這麼作」。框架

而伴隨着雲計算和容器技術的發展,微服務的出現,恰巧將這些問題迎刃而解。
圖片描述

( 上圖: 容器技術的基本層次結構 )

先來講說容器技術的表明 —— Docker

Docker 能夠看做是輕量級的虛擬機——它能夠經過「容器鏡像」快速啓動和中止預先配置好的相應運行環境。每個容器均可以被看做一個獨立的操做系統,相互隔離,互不干擾。所以,藉助docker 咱們就能夠針對一個應用中不一樣的功能,爲其獨立定製運行環境,獨立裝載依賴和工具庫,獨立運行獨立中止,獨立升級,每一個功能可使用其最適合的編程語言進行開發,也將整個應用拘泥於一種框架了。利用 docker 將每一個模塊在操做系統層面進行隔離,對於每一個模塊均可以獨立管理其生命週期了,這就是「微服務」中「微」字的具體含義。

微服務開發的重點

基於這種開發方式,每一個功能模塊能夠被獨立開發,獨立部署,獨立運行,獨立進行版本控制,等等。而對於規模比較龐大的系統來講,這種利用微服務架構所開發的應用,其自然的優點就更能體現出來了——即每一個模塊能夠獨立的團隊由單獨負責。所以,微服務開發中的第一個重點,就是要有很是明確的需求,以及一個經驗豐富的架構師,在設計之初就對各個功能模塊進行合理的規劃和拆分。

在整個應用設計之初由總設計師或架構師設計好各個功能模塊後,第二個重點就來了:設計微服務中各個模塊間的調用接口——一般由 Rest API 或者 gRPC 組成——來負責模塊之間的交互,這就是微服務的第二個重點。良好的接口設計將會使你的應用結構清晰,開發起來事半功倍。並且每一個獨立團隊在開發時都能感覺到明顯的模塊邊界,且能夠放心利用模擬數據和測試數據進行開發( 只要符合接口規則的數據就能用,不用操心其餘模塊是如何實現的 ),從而真正實現每一個團隊富有效率的並行開發。

利用微服務架構開發除了上述好處以外,在運維方面的優點也很是直觀——咱們能夠清晰地觀測到整個系統的資源瓶頸在何處( 哪一個容器的資源開銷最大 ),從而實現有針對性的「定向擴縮容」。利用微服務架構先後的擴縮容機制以下圖所示意。

圖片描述

( 上圖: 單體應用和微服務應用最直觀的差異:定向擴縮容 示意圖 )

將龐大的單體應用逐步改形成微服務應用

在看完上面的介紹後,相信飽受單體應用折磨的各位讀者已經對微服務開發已經躍躍欲試了。可是,對於一個正在運行並使用的應用來講,完徹底全從零開始開發並不現實。對於一個已經成熟並正在使用的單體應用系統來講,咱們能夠經過本身的努力,將一個單體應用在幾回迭代過程當中,逐漸改變爲微服務應用。如何辦到呢?下面放一張圖片來幫助您激發靈感:

圖片描述

( 上圖: 熱帶雨林中的參天大樹與附着在其上的藤蔓 )

沒錯,就像您所想到的那樣:在這幅圖中,龐大的樹木表明着咱們原有的單體項目,而樹外所覆蓋着的藤蔓就象徵着微服務組件。在將您的單體應用微服務化時,也能夠採用這種方式,即:新的功能使用微服務架構來開發,經過對原有的單體應用暴露 IP 和端口號的方式供其進行調用和使用。

利用這種方式,您以後新開發的功能所對應的軟件實體就都是基於微服務架構的了。這樣隨着時間的推移和版本的逐漸迭代,採用微服務架構所開發的部分所佔比例愈來愈大,最後原來的單體應用也逐漸變爲了整個應用中的一個獨立服務,您的軟件架構就完全地完成了微服務化。

這種改造方式來源於 Chris Richardson 的系列博文中的一篇,若是您對這方面內容感興趣的話,歡迎您移步其博客一探究竟( 博客的中文翻譯連接: https://www.jianshu.com/p/29f... )。因爲內容過多,在此再也不展開討論一一贅述。

Happy Ending,十全十美了?

顯然不是,技術的發展歷來沒有止境,也不存在止鏡。微服務的出現,雖然解決了傳統軟件開發結構龐大、模塊複雜等諸多難點,可是解決了原有的問題後,新的問題又浮出了水面:微服務應用的每一個基本單元之間調用關係複雜、網絡位置處於動態變化、且每一個組件的生命週期都各自獨立,所以難以實現統一的管理。

這裏說的可能有些抽象,那麼就爲你們舉一個小例子:請你們設想一個簡單的場景:每個微服務組件都有一個本身獨有的網絡位置( 在因特網中就是咱們最經常使用的 IP 和端口號 ),以此來惟一肯定一個服務;其餘服務若想調用本服務,就須要知道該服務的 IP 和端口號,以此對其發送網絡請求。

細心的朋友可能已經察覺到問題了:對於一個微服務架構的應用場景,微服務的每個組件都是不斷處於動態擴縮容的狀態中的,可能上一秒這個 IP 和端口號還對應着相應的組件,下一秒這個組件就因爲當前訪問量的降低而被節約成本,自動地縮容釋放掉了。若是這時其餘服務再來訪問這個 IP 和端口號,那必定會出現找不到服務等各類故障。

圖片描述

( 上圖: 多變的網絡位置是微服務管理中的一大難題 )

架構改變所帶來的諸如此類的問題還有許多,在此就不一一列舉了。準備將本身的軟件架構進行微服務化的朋友們須要三思:改變一種軟件架構可能會解決許多曾經的架構所存在的問題,但同時也會帶來不少原有架構不會出現的新問題。

不過幸虧微服務架構已經有很多國內外的大公司和優秀團隊做爲先驅,率先摸着石頭過了一次河,而且告訴了咱們許多過河的寶貴經驗,甚至已經有許多工具和開源項目被開發出來,幫助咱們解決剛纔分析到的種種問題了。

在目前種種微服務場景的解決方案中,有兩種是使用最爲廣泛、同時也廣受好評的。它們分別是較早出現的 Spring Cloud 框架,以及近幾年微服務領域最爲流行的 Service Mesh 微服務管理框架。因爲 Service Mesh 所帶來的「業務代碼零侵入」、「直接與容器管理框架(如 K8s )集成」等諸多優勢,所以基於 Service Mesh 的微服務開發和蔚雲方式正在逐漸成爲主流,特別是 Google 宣佈了其 Istio 項目能夠與 K8s 完美集成後,國內外社區的開發者對 Service Mesh 的發展更是翹首以盼。下面就對 Service Mesh 進行一下簡單的介紹。

何爲 "Service Mesh"

「A service mesh is a dedicated infrastructure layer for handling service-to-service communication. 「 —— William Morgan( Founder of Service Mesh )

Service Mesh 是一個專一於處理服務間通訊的基礎設施層。
雲原生應用有着複雜的服務拓撲,而 Service Mesh 保證請求能夠在這些拓撲中可靠地穿梭。在實際應用當中,Service Mesh 一般是由一系列輕量級的網絡代理組成的,它們與應用程序部署在一塊兒,但應用程序不須要知道它們的存在。

圖片描述

( 上圖: Service Mesh 示意圖——幫助您管理錯誤複雜的微服務應用 )

技術起源與出現背景

Service Mesh 的概念最先由前 twitter 的基礎設施工程師 William Morgan 於 2017 年 4 月 25 日提出。雖然在此以前,微服務領域也有相似的概念被提出或用於開發項目,但在業界始終沒有一個統一的名稱。 William Morgan 在本身的博文 "What’s a service mesh? And why do I need one?" 中正式給 Service Mesh 作出了權威的定義。至此,"Service Mesh" 這個名詞正式出如今各大公司以及技術社區的視野中。

隨着雲計算的普及,愈來愈多的開發者和企業開始使用「微服務」的開發模式。這種開發模式擁有諸如耦合度低、跨語言開發、更小粒度擴容等許多優點,但一樣也面臨着許多挑戰,就如咱們上文所分析的那樣。

Service Mesh 的發展

Service Mesh 從出現至今總共經歷了三個階段:微服務初期、Sidecar 時期和 Service Mesh 時期。

微服務初期

在微服務初期( 2015年前 )開發微服務應用的過程當中,咱們須要重複性地處理一系列基礎工做,好比:服務註冊、服務發現、獲得服務實例後的負載均衡、熔斷機制等。這些工做在 Service Mesh 出現以前通通都要開發人員在項目中用代碼解決並實現,致使應用程序中加入了大量的非功能性代碼。即便使用相似 Netflix OSS 的庫和 Spring Cloud 的框架,開發人員依然面臨着需掌握內容多、技術門檻高等諸多困難。

Sidecar 的出現

圖片描述

( 上圖: Sidecar ,中文意思爲摩托車的跨鬥,不禁讚歎命名的很是生動 )

"Sidecar" 這個詞,本人使用 Google 搜索引擎同時檢索 sidecar 和 microservices 這兩個關鍵字並按時間順序排序,最先出現的檢索結果是在 2014 年 5 月 14 日的這篇演講中。根據本人查閱的資料顯示,"Sidecar" 這個名詞最先由 Netflix 提出並被用於 Eureka 項目。因爲這個項目的普遍應用,故在此以後,凡是微服務中「用於端對端通訊的、被單獨分離出來的「組件,就都被稱爲 "Sidecar" 了。

仔細分析上述一系列的重複性工做,咱們能夠發現,這些工做幾乎所有集中在處理各個服務間的通訊問題。那麼,爲什麼咱們不把這些工做從業務邏輯中抽離出來,使其專一於服務間通訊,並造成單獨的組件呢?
Sidecar 模式,即在微服務中將關於服務通信的功能抽離出來,並做爲一個單獨的組件運行在微服務中。這種在微服務中獨立負責端對端通訊的組件,咱們稱之爲 Sidecar 。這種在微服務中將業務邏輯與服務通訊解藕,並分離爲兩個獨立運行組件的作法,正是 Service Mesh 概念的雛形。
但在這個階段,每一個微服務中的 Sidecar 還沒法通用,即這個微服務的 Sidecar 沒有辦法拆出來給另外一個微服務使用。

Service Mesh 的提出

Service Mesh 在 Sidecar 模式的基礎上更進一步。Service Mesh 的定義——一個專一於處理服務間通訊的基礎設施層——站在開發者的角度來說,就是在每個微服務中將用於通訊的部分從業務中完全解藕,應用程序甚至不須要知道它們的存在。在 Service Mesh 中,每一個微服務至少含有兩個組件:一個用於處理業務功能的「應用程序」和一個專職處理服務間通訊的「 Sidecar 」( 相似網絡代理 )。

Service Mesh 的願景是但願開發者不再須要將精力花費在服務通訊上。服務通訊由每一個微服務的 Sidecar 負責,而 Sidecar 由專門的項目來接管。目前,許多被熟知的項目均可以被咱們看成 Sidecar 來運用,好比 Envoy 、 HAProxy 和 Nginx 。

使用了 Service Mesh 以後,開發團隊和運維團隊就能夠更加明確的劃清本身的職責範圍——開發團隊專一於業務的開發,而運維團隊只需關注微服務中的 Sidecar 就能夠明確地瞭解到每一個微服務的健康狀況和各類指標。

圖片描述

( 上圖: 「Service Mesh」一詞成爲技術術語,首次在公衆場合亮相 )

Service Mesh 的設計理念和做用

隨着雲原生應用的崛起,Service Mesh 逐漸成爲一個獨立的基礎設施層。在雲原生模型裏,一個應用能夠由數百個服務組成,每一個服務可能有數千個實例,而每一個實例可能會持續地發生變化。服務間通訊不只異常複雜,並且也是運行時行爲的基礎。管理好服務間通訊對於保證端到端的性能和可靠性來講是很是重要的。

Service Mesh 實際上就是處於 TCP/IP 之上的一個抽象層,它假設底層的 L3/L4 網絡可以點對點地傳輸字節(固然,它也假設網絡環境是不可靠的,因此 Service Mesh 也必須具有處理網絡故障的能力)。

從某種程度上說,Service Mesh 有點相似 TCP/IP 。TCP 對網絡端點間傳輸字節的機制進行了抽象,而Service Mesh則是對服務節點間請求的路由機制進行了抽象。Service Mesh 不關心消息體是什麼,也不關心它們是如何編碼的。應用程序的目標是「將某些東西從A傳送到B」,而 Service Mesh 所要作的就是實現這個目標,並處理傳送過程當中可能出現的任何故障。

與TCP不一樣的是,Service Mesh有着更高的目標:爲應用運行時提供統一的、應用層面的可見性和可控性。經過每一個微服務中的 Sidecar ,Service Mesh 得以將服務間通訊從底層的基礎設施中分離出來,讓它成爲整個生態系統的一等公民——它再也不是單純的基礎設施,更能夠被監控、託管和控制。

Service Mesh 的將來

儘管 Service Mesh 在雲原生系統方面的應用已經有了快速的增加,但仍然存在巨大的提高空間。服務發現和訪問策略在雲原生環境中仍顯初級,而 Service Mesh 毫無疑問將成爲這方面不可或缺的基礎。就像 TCP/IP 做爲互聯網的基礎同樣,Service Mesh 將在微服務的底層基礎設施這條路上更進一步。

總結及展望

本文主要介紹了兩個關鍵點:當下最爲流行的一種軟件開發架構——微服務架構、以及解決微服務架構帶來的種種問題的微服務管理模型——Service Mesh(服務網格)模型。

在使用微服務架構開發應用的初期,你們必定會沉醉於其清晰的模塊邊界和獨立運行所帶來的種種便利。然而,這並非說微服務應用就已經十全十美了。隨着一個龐大的單體應用被拆分爲細碎的各個微小模塊,若是對它們進行有效的管理就成爲了新的挑戰。畢竟,一箇中等體量的應用被微服務化後,幾百個小模塊同時運行是常有的事兒。那麼,如何控制服務之間的調用?如何定位這些服務( 你知道,在這種場景下手動修改配置文件指定其餘服務的 IP 和 port 已經不現實了 )?如何將出現錯誤的應用及時熔斷?這都是亟待咱們解決的事情,也是目前微服務架構所發展的主要方向。

在熟練運用 Docker 後,咱們能夠繼續去學習 Kubernetes,一款由 Google 和 IBM 共同開發的開源「容器集羣管理框架」,相似於控制容器的「操做系統」。

而微服務所面臨的上述種種問題,目前咱們能夠藉助一樣由 Google 開發的 Istio(服務網格的一種) 來解決,諸如服務註冊、服務發現、服務治理、流量管理和容錯機制等等。其基本層次關係以下圖所示。

圖片描述

( 上圖: 本身整理的「目前微服務架構的技術棧」,但願各位讀者有所幫助 )

但願本篇文章可以成爲您開展微服務相關工做的參考,爲您瞭解爲服務理念、轉型微服務架構提供幫助。文章中若是存在遺漏或錯誤,也很是歡迎您指出,很是期待與您的交流與討論。

相關文章
相關標籤/搜索