Service Mesh——微服務中的流量管理中間件
Service mesh 與 Cloud Native
Kubernetes 設計之初就是按照 Cloud Native 的理念設計的,Cloud Native 中有個重要概念就是微服務的架構設計,當將單體應用拆分微服務后, 隨着服務數量的增多,如何微服務進行管理以保證服務的 SLA 呢?為了從架構層面上解決這個問題,解放程序員的創造性,避免繁瑣的服務發現、監控、分布式追蹤等事務,Service mesh 應運而生。
什么是 service mesh?
最近聽了58孫玄老師的課 大致總結一下 service mesh
service mesh是在微服務的基礎上 把一些類似限流、降級 服務發現 熔斷 ,服務追蹤等服務治理組件,理論上這些都應該是中間件團隊可以來搞優化,我們可以把它們抽離出來 在很業務進程部署在同一主機 搞成一個sidecar ,業務進程只需要關注業務代碼就行了,不需要去植入很多服務治理相關的事情,服務於服務間的注冊也好 熔斷也好 通過sidecar通信,sidecar來實現 ;sidecar與另一台主機的sidecar進行通信治理。
這里需要注意的是 幾個問題
- sidecar部署在本地主機 因為這樣通信 路由都很好解決
Service mesh 有如下幾個特點:
- 應用程序間通訊的中間層
- 輕量級網絡代理
- 應用程序無感知
- 解耦應用程序的重試/超時、監控、追蹤和服務發現
目前兩款流行的 service mesh 開源軟件 Istio 和 Linkerd 都可以直接在 kubernetes 中集成,其中 Linkerd 已經成為 CNCF 成員。
理解 Service Mesh
如果用一句話來解釋什么是 Service Mesh,可以將它比作是應用程序或者說微服務間的 TCP/IP,負責服務之間的網絡調用、限流、熔斷和監控。對於編寫應用程序來說一般無須關心 TCP/IP 這一層(比如通過 HTTP 協議的 RESTful 應用),同樣使用 Service Mesh 也就無須關系服務之間的那些原來是通過應用程序或者其他框架實現的事情,比如 Spring Cloud、OSS,現在只要交給 Service Mesh 就可以了。
Phil Calçado 在他的這篇博客 Pattern: Service Mesh 中詳細解釋了 Service Mesh 的來龍去脈:
- 從最原始的主機之間直接使用網線相連
- 網絡層的出現
- 集成到應用程序內部的控制流
- 分解到應用程序外部的控制流
- 應用程序的中集成服務發現和斷路器
- 出現了專門用於服務發現和斷路器的軟件包/庫,如 Twitter 的 Finagle 和 Facebook 的 Proxygen,這時候還是集成在應用程序內部
- 出現了專門用於服務發現和斷路器的開源軟件,如 Netflix OSS、Airbnb 的 synapse 和 nerve
- 最后作為微服務的中間層 service mesh 出現
Service mesh 的架構如下圖所示:

Service mesh 作為 sidecar 運行,對應用程序來說是透明,所有應用程序間的流量都會通過它,所以對應用程序流量的控制都可以在 serivce mesh 中實現。
Service mesh如何工作?
下面以 Linkerd 為例講解 service mesh 如何工作,Istio 作為 service mesh 的另一種實現原理與 linkerd 基本類似,后續文章將會詳解 Istio 和 Linkerd 如何在 kubernetes 中工作。
- Linkerd 將服務請求路由到目的地址,根據中的參數判斷是到生產環境、測試環境還是 staging 環境中的服務(服務可能同時部署在這三個環境中),是路由到本地環境還是公有雲環境?所有的這些路由信息可以動態配置,可以是全局配置也可以為某些服務單獨配置。
- 當 Linkerd 確認了目的地址后,將流量發送到相應服務發現端點,在 kubernetes 中是 service,然后 service 會將服務轉發給后端的實例。
- Linkerd 根據它觀測到最近請求的延遲時間,選擇出所有應用程序的實例中響應最快的實例。
- Linkerd 將請求發送給該實例,同時記錄響應類型和延遲數據。
- 如果該實例掛了、不響應了或者進程不工作了,Linkerd 將把請求發送到其他實例上重試。
- 如果該實例持續返回 error,Linkerd 會將該實例從負載均衡池中移除,稍后再周期性得重試。
- 如果請求的截止時間已過,Linkerd 主動失敗該請求,而不是再次嘗試添加負載。
- Linkerd 以 metric 和分布式追蹤的形式捕獲上述行為的各個方面,這些追蹤信息將發送到集中 metric 系統。
為何使用 service mesh?
Service mesh 並沒有給我們帶來新功能,它是用於解決其他工具已經解決過的問題,只不過這次是在 Cloud Native 的 kubernetes 環境下的實現。
在傳統的 MVC 三層 Web 應用程序架構下,服務之間的通訊並不復雜,在應用程序內部自己管理即可,但是在現今的復雜的大型網站情況下,單體應用被分解為眾多的微服務,服務之間的依賴和通訊十分復雜,出現了 twitter 開發的 Finagle、Netflix 開發的 Hystrix 和 Google 的 Stubby 這樣的 ”胖客戶端“ 庫,這些就是早期的 service mesh,但是它們都近適用於特定的環境和特定的開發語言,並不能作為平台級的 service mesh 支持。
在 Cloud Native 架構下,容器的使用給予了異構應用程序的更多可行性,kubernetes 增強的應用的橫向擴容能力,用戶可以快速的編排出復雜環境、復雜依賴關系的應用程序,同時開發者又無須過分關心應用程序的監控、擴展性、服務發現和分布式追蹤這些繁瑣的事情而專注於程序開發,賦予開發者更多的創造性。