一文深入理解Service Mesh 服務網格

首先,給出Service  Mesh 的定義:

服務網格是一個基礎設施層,用於處理服務間通訊。雲原生應用有着複雜的服務拓撲,服務網格負責在這些拓撲中實現請求的可靠傳遞。在實踐中,服務網格通常實現爲一組輕量級網絡代理,它們與應用程序部署在一起,而對應用程序透明。

那麼服務網格使用在什麼場景下呢? 簡單地說來就是爲了解決就是微服務場景下的一系列問題。

微服務(Microservices)是一種軟件架構風格,它是以專注於單一責任與功能的小型功能區塊(Small Building Blocks)爲基礎,利用模塊化的方式組合出複雜的大型應用程序,各功能區塊使用與語言無關(Language-Independent /Language agnostic)的API集相互通信。

 

微服務痛點

比如在實現微服務的時候要處理一系列的比較基礎和通用的事項,如服務發現,在得到服務器實例列表之後再做負載均衡,爲了保護服務器要熔斷/重試等等。

這些功能所有的微服務都需要,那怎麼辦呢?如果將這些功能直接在應用程序裏面實現,應用程序裏面又加上了大量的非業務相關的代碼。很自然的,爲了簡化開發避免代碼重複,我們選擇使用類庫,如經典的Netflix OSS套件。這樣開發人員的重複編碼問題就解決了:只需要寫少量代碼,就可以藉助類庫實現這些功能。

因爲這個原因,最近這些年大家看到Java社區Spring Cloud的普及程度非常快,幾乎成爲了微服務的代名詞。但這一切都完美了嗎?

 

侵入式框架的痛點:

以Spring Cloud/Dubbo爲代表的傳統微服務框架,是以類庫的形式存在,通過重用類庫來實現功能和避免代碼重複。但在以運行時操作系統進程的角度來看,這些類庫還是滲透進了打包部署之後的業務應用程序,和業務應用程序運行在同一進程內。所謂”侵入式框架”的稱謂由此而來。

而建立在類庫基礎上的”侵入式框架”,會面臨與生俱來的諸多痛點。

 

微服務在面世時,承諾了一個很重要的特性:微服務可以採用最適合的語言來編寫。理論上說,不同的團隊,不同的微服務,可以根據實際情況選擇團隊最擅長,或者最適合當前應用的編程語言。

但是,在實踐中,這個承諾往往受到極大挑戰而淪爲空話:微服務的確理論上可以使用不同的語言,但是實際開發時,當需要選擇通過框架或者類庫來實現代碼重用時,就會發現有個繞不開的問題——框架和類庫是語言強相關的!

任何框架不可能一開始就完美無缺,所有功能都齊備,沒有任何BUG,以至於分發出去之後就再也不需要改動和升級。這種理想狀態是不存在的。必然是1.01.22.0慢慢版本升級,功能逐漸增加,BUG逐漸被修復。在這期間,一個接一個新版本陸續發佈並分發給使用者。但是,當框架分發給使用者之後,使用者會不會總是保持升級到最新發布的版本?

隨着時間的推移會越來越呈現出版本碎片化的趨勢。此時,不同版本之間的兼容性問題就會變得非常的複雜,框架的開發人員需要非常小心的維護兼容性,一旦兼容性出現問題,就會嚴重打擊使用者升級的慾望,造成更大的碎片化,惡性循環。

 

解決思路

問題的根源在哪裏?

面臨的這些問題,這麼多艱鉅的挑戰,和業務應用,或者說服務本身,有直接關係嗎?

答案是:沒有。這些問題都屬於服務間通訊的範圍,和應用本身的實現邏輯無關。

我們的目標是什麼?

所有的努力,都是爲了保證將客戶端發出的業務請求,發送到正確的目的地。而”正確”一詞,在不同的特性下有不同的語義,如服務發現,負載均衡,灰度,版本控制,藍綠部署,按照請求內容執行不同的路由策略。服務間通訊的目標,是讓請求在滿足這些特性要求的前提下,去往請求應該去的目的地服務,而與請求的業務語義無關,和請求的業務處理無關。

服務間通訊的本質是什麼?

在整個服務間通訊的處理流程中,無論功能有多複雜,請求本身的業務語義和業務內容(非業務內容可能會有變化如傳遞特殊的header或者對內容加解密)是不發生變化的。對於服務間通訊,實現的是請求的可靠傳遞,內容是不變的。

有什麼內容是普適的?

前面遇到的這些問題具有高度的普適性:適用於所有的語言、框架、組織,這些問題對於任何一個微服務都是同樣存在的。

 

Service Mesh-Istio

所以爲了解決以上微服務在實際落地中的種種問題, service mesh就出場了。來看下它是怎麼爲微服務賦能的:

 

有了這個東西,就真正的把業務和基礎通信徹底剝離了,開發者真正關心得是業務,徹徹底底的原生了。把這些業務程序放在雲上跑,哈哈,那就是雲原生的時代了。

將非業務邏輯的功能實現,從客戶端SDK中剝離出來,放到獨立的 Proxy 進程中,這是 Service Mesh 在技術實現上走出的第一步,也是至關重要的第一步:因爲這一步,實現了業務邏輯非業務邏輯的分離,而且是最徹底的物理分離,哪怕需要爲此付出一次遠程調用的代價。

而這一步邁出之後,前面就是海闊天空:

  • 業務邏輯和非業務邏輯分離之後,我們就可以將這些非業務邏輯繼續下沉
  • 下沉到基礎設施,基礎設施可以是基於VM的,可以是基於容器和k8s的;也可以是VM和容器混合
  • 基礎設施也可以以雲的形式提供,可以是公有云、私有云,也可以是混合雲、多雲;
  • 可以選擇雲上託管,完全託管也好,部分託管也好,產品形態可以很靈活

總結說,業務邏輯和非業務邏輯的分離:

  • 爲下沉到基礎設施提供可能
  • 爲上雲提供可能
  • 爲應用輕量化提供可能

 

Service Mesh 的最成功的實踐者:Istio

從邏輯上,Istio分爲數據平面控制平面兩個部分:

  • 數據平面是以 sidecar 方式部署的智能代理,Istio默認集成的是Envoy。數據平面用來控制微服務之間的網絡通訊,以及和Mixer模塊通信。
  • 控制平面負責管理和配置數據平面,控制數據平面的行爲,如代理路由流量,實施策略,收集遙測數據,加密認證等。控制平面分爲Pilot、Mixer、Citadel三個組件,後面再詳細介紹。

下圖是Istio官方文檔中的配圖,詳細描述了數據平面和控制平面的組成、調用關係和主要職責。

關於Istio 的更加詳細的解讀,可以參考:https://skyao.io/learning-servicemesh/istio/architecture.html ,https://github.com/istio/istio

Service Mesh模式可以歸結爲以下三點:

  1. 以原生模式開發應用
  2. 以標準模式部署應用:底下發生了什麼不關心
  3. 客戶端簡單發一個請求給服務器端:底下是如何實現的同樣不關心,應用只知道請求最終順利發送完成

Service Mesh產品的存在和具體工作模式,對於運行於其上的雲原生應用來說是透明無感知的,但是在運行時這些能力都動態賦能給了應用,從而幫助應用在輕量化的同時依然可以繼續提供原有的功能。

Mesh模式不僅僅可以用於服務間通訊,也可以應用於更多的場景:

  • Database mesh:用於數據庫訪問
  • Message mesh:用於消息系統

雲原生指 “原生爲雲設計”,具體說就是:應用原生被設計爲在雲上以最佳方式運行,充分發揮雲的優勢。 

雲原生賦能(Cloud Empower)的基本工作原理:

  • 首先要將功能實現從應用中剝離出來:這是應用輕量化的前提和基礎
  • 然後在運行時爲應用 動態賦能:給應用的賦能方式也要雲原生化,要求在運行時動態提供能力,而應用無感知

這些技術之間的關係可以用下面這張圖來囊括:

 

  • 爲了解決單體的複雜度問題,我們引入微服務架構
  • 爲了解決微服務架構下大量應用部署的問題,我們引入容器
  • 爲了解決容器的管理和調度問題,我們引入kubernetes
  • 爲了解決微服務框架的侵入性問題,我們引入Service Mesh
  • 爲了讓 Service Mesh 有更好的底層支撐,我們又將 Service Mesh 運行在 k8s上

雲原生是一個理想的夢想,要實現他就得有各種方法和手段,簡單歸納有以下方面的技術:

未來的發展方向:

如上圖所示:

  • 最下方是雲,基於k8s和容器打造,提供各種基礎能力,這些能力有一部分來自傳統中間件的下沉
  • 在雲上是 Mesh 層,包含 Service Mesh 以及我們前面提到的各種擴展的Mesh模式,實現通信的標準化
  • 在通過 Mesh 剝離非業務功能並下沉之後,應用實現了輕量化,傳統的App和新興的微服務都可以受益於此
  • 更進一步,輕量化之後的業務應用,其工作負載在瘦身減負之後變得相當的乾淨,基本只剩業務邏輯,包括傳統的App,以Container形式運行的服務和新穎的Function,這些負載在往 Serverless 形態轉換時相對要輕鬆很多

配合 Serverless 技術領域最新的技術潮流和產品發展,Mesh化爲現有應用轉型爲 Serverless 模式提供助力。

 

參考資料:

https://skyao.io/learning-servicemesh/

https://skyao.io/talk/201905-servicemesh-development-trend/

https://skyao.io/talk/201810-ant-finance-service-mesh-practice/

https://skyao.io/talk/201902-cloudnative-freely-talk/

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