微服務架構ServiceMesh

公司用的架構,在此找了資料做爲記錄復看所用:算法

什麼是Service Mesh?

Service Mesh的概念最先是由Buoyant公司的CEO William Morgan在一篇文章裏提出,他給出的服務網格的定義是:安全

A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.網絡

Service Mesh是一種新型的用於處理服務與服務之間通訊的技術,尤爲適用以雲原生應用形式部署的服務,可以保證服務與服務之間調用的可靠性。在實際部署時,Service Mesh一般以輕量級的網絡代理的方式跟應用的代碼部署在一塊兒,從而以應用無感知的方式實現服務治理。架構

Service Mesh以輕量級的網絡代理的方式與應用的代碼部署在一塊兒,用於保證服務與服務之間調用的可靠性,這與傳統的微服務架構有着本質的區別,這麼作主要是出於兩個緣由。app

1.跨語言服務調用的須要。在大多數公司內一般都存在多個業務團隊,每一個團隊業務所採用的開發語言通常都不相同,以微博的業務爲例,移動服務端的業務主要採用的是PHP語言開發,API平臺的業務主要採用的是Java語言開發,移動服務端調用API平臺使用的是HTTP請求,若是要進行服務化,改爲RPC調用,就須要一種既支持PHP語言又支持支持Java語言的的服務化框架。負載均衡

2.雲原生應用服務治理的須要。在微服務愈來愈多開始容器化,並使用Kubernetes相似的容器平臺對服務進行管理,逐步朝雲原生應用的方向進化。而傳統的服務治理要求在業務代碼裏集成服務框架的SDK,這顯然與雲原生應用的理念相悖,所以迫切須要一種對業務代碼無侵入的適合雲原生應用的服務治理方式。框架

在這種背景下,Buoyant公司開發的第一代Service Mesh產品Linkerd應運而生。從下圖中能夠看到,服務A要調用服務B,通過Linkerd來代理轉發,服務A和服務B的業務代碼不須要關心服務框架功能的實現。爲此Linkerd須要具有負載均衡、熔斷、超時重試、監控統計以及服務路由等功能。這樣的話,對於跨語言服務調用來講,即便服務消費者和服務提供者採用的語言不一樣,也不須要集成各自語言的SDK。ide


(圖片來源:https://linkerd.io/images/what_it_does@2x.png微服務

而對於雲原生應用來講,能夠在每一個服務部署的實例上,都同等的部署一個Linkerd實例。好比下面這張圖,服務A要想調用服務B,首先調用本地的Linkerd實例,通過本地的Linked實例轉發給服務B所在節點上的Linkerd實例,最後再由服務B本地的Linkerd實例把請求轉發給服務B。這樣的話,全部的服務調用都得通過Linkerd進行代理轉發,全部的Linkerd組合起來就像一個網格同樣,這也是爲何咱們把這項技術稱爲Service Mesh,也就是「服務網格」的緣由。性能


(圖片來源:https://buoyant.io/wp-content/uploads/2017/04/linkerd-service-mesh-diagram-1024x587.png

Service Mesh的實現原理

Service Mesh實現的關鍵就在於兩點:一個是上面提到的輕量級的網絡代理也叫SideCar,它的做用就是轉發服務之間的調用;一個是基於SideCar的服務治理也被叫做Control Plane,它的做用是向SideCar發送各類指令,以完成各類服務治理功能。下面我就來詳細講解這兩點是如何實現的。

1.SideCar

咱們首先來看一下,在傳統的微服務架構下服務調用的原理。你能夠看下面這張圖,服務消費者這邊除了自身的業務邏輯實現外,還須要集成部分服務框架的邏輯,好比服務發現、負載均衡、熔斷降級、封裝調用等,而服務提供者這邊除了實現服務的業務邏輯外,也要集成部分服務框架的邏輯,好比線程池、限流降級、服務註冊等。

而在Service Mesh架構中,服務框架的功能都集中實如今SideCar裏,並在每個服務消費者和服務提供者的本地都部署一個SideCar,服務消費者和服務提供者只管本身的業務實現,服務消費者向本地的SideCar發起請求,本地的SideCar根據請求的路徑向註冊中心查詢,獲得服務提供者的可用節點列表後,再根據負載均衡策略選擇一個服務提供者節點,並向這個節點上的SideCar轉發請求,服務提供者節點上的SideCar完成流量統計、限流等功能後,再把請求轉發給本地部署的服務提供者進程,從而完成一次服務請求。整個流程你能夠參考下面這張圖。

咱們能夠把服務消費者節點上的SideCar叫做正向代理,服務提供者節點上的SideCar叫做反向代理,那麼Service Mesh架構的關鍵點就在於服務消費者發出的請求如何經過正向代理轉發以及服務提供者收到的請求如何經過反向代理轉發。從個人經驗來看,主要有兩種實現方案。

  • 基於iptables的網絡攔截。這種方案請見下圖,節點A上服務消費者發出的TCP請求都會被攔截,而後發送給正向代理監聽的端口15001,正向代理處理完成後再把請求轉發到節點B的端口9080。節點B端口9080上的全部請求都會被攔截髮送給反向代理監聽的端口15001,反向代理處理完後再轉發給本機上服務提供者監聽的端口9080。

  • 採用協議轉換的方式。這種方案請見下圖,節點A上的服務消費者請求直接發給正向代理監聽的端口15001,正向代理處理完成後,再把請求轉發到節點B上反向代理監聽的端口15001,反向代理處理完成後再發送給本機上的服務提供者監聽的端口9080。

可見,這兩種方案最大的不一樣之處在於,一個是經過iptables網絡攔截實現代理轉發的,一個是靠直接把請求發送給代理來轉發的。基於iptables網絡攔截的方式,理論上會有必定的性能損耗,但它的優勢是從網絡層實現調用攔截,能作到徹底的業務無感知,因此適合雲原生應用。而直接把請求發送給代理的方式,要求代理層加入業務邏輯,才能把請求轉發給對應的服務提供者監聽的端口。

2.Control Plane

既然SideCar能實現服務之間的調用攔截功能,那麼服務之間的全部流量均可以經過SideCar來轉發,這樣的話全部的SideCar就組成了一個服務網格,再經過一個統一的地方與各個SideCar交互,就能控制網格中流量的運轉了,這個統一的地方就在Sevice Mesh中就被稱爲Control Plane。以下圖所示,Control Plane的主要做用包括如下幾個方面:

  • 服務發現。服務提供者會經過SideCar註冊到Control Plane的註冊中心,這樣的話服務消費者把請求發送給SideCar後,SideCar就會查詢Control Plane的註冊中心來獲取服務提供者節點列表。

  • 負載均衡。SideCar從Control Plane獲取到服務提供者節點列表信息後,就須要按照必定的負載均衡算法從可用的節點列表中選取一個節點發起調用,能夠經過Control Plane動態修改SideCar中的負載均衡配置。

  • 請求路由。SideCar從Control Plane獲取的服務提供者節點列表,也能夠經過Control Plane來動態改變,好比須要進行A/B測試、灰度發佈或者流量切換時,就能夠動態地改變請求路由。

  • 故障處理。服務之間的調用若是出現故障,就須要加以控制,一般的手段有超時重試、熔斷等,這些均可以在SideCar轉發請求時,經過Control Plane動態配置。

  • 安全認證。能夠經過Control Plane控制一個服務能夠被誰訪問,以及訪問哪些信息。

  • 監控上報。全部SideCar轉發的請求信息,都會發送到Control Plane,再由Control Plane發送給監控系統,好比Prometheus等。

  • 日誌記錄。全部SideCar轉發的日誌信息,也會發送到Control Plane,再由Control Plane發送給日誌系統,好比Stackdriver等。

  • 配額控制。能夠在Control Plane裏給服務的每一個調用方配置最大調用次數,在SideCar轉發請求給某個服務時,會審計調用是否超出服務對應的次數限制。

相關文章
相關標籤/搜索