微服務的服務間通訊與服務治理是微服務架構的實現層面的兩大核心問題。html
本文但願經過結合扇貝生產環境中的實踐(百萬日活場景),給你們分享相關的經驗心得。node
從通訊類型的角度看,大概有三種類型:同步調用,異步調用,廣播。python
在微服務的設計之初要想清楚調用關係以及調用方式,哪些須要同步,哪些能夠異步,哪些須要廣播,最好團隊內部要有統一的認識。git
而後就是要肯定好調用協議了,例如常見的選擇有:github
對於如何選擇,咱們須要從不少角度去思考。網上有大量的 "X vs Y"的文章或問答。其實無非就是從幾個角度:性能,成熟度,易用性,生態,技術團隊。咱們的建議是:優先選擇社區活躍,以及和本身團隊技術棧相融的。社區活躍的技術每每表明了趨勢和生態,而團隊技術棧的相容性則是可否落地成功的保證。網絡
好比當時扇貝選擇gRPC
做爲同步調用的接口協議。主要考慮的就是兩點:1. 社區活躍,發展很是迅速;2.基於 HTTP/2,與咱們的技術棧相容。架構
除了選擇協議,更加劇要的應該就是接口文檔的管理了。最好接口文檔和代碼是強相關的,就像 gRPC 的 proto 和生成出來的代碼那樣。不然人每每是有惰性的,頗有可能代碼改了文檔沒改。負載均衡
總之,關於服務間通訊,咱們須要作好:框架
服務治理是個很是大的話題,真的要鋪開來說,可能幾篇文章的篇幅都講不完。這裏咱們想先簡單地看一下服務治理要解決的問題,以及如今的一些解決方案,發展趨勢。
最後以扇貝爲例,簡單介紹下在一個真實的百萬日活的生產環境中,服務治理是如何作的。異步
什麼是服務治理
微服務化帶來了不少好處,例如:經過將複雜系統切分爲若干個微服務來分解和下降複雜度,使得這些微服務易於被小型的開發團隊所理解和維護。然而也帶來了不少挑戰,例如:微服務的鏈接、服務註冊、服務發現、負載均衡、監控、AB測試,金絲雀發佈、限流、訪問控制,等等。
這些挑戰便是服務治理的內容。
現有方案
服務治理的問題由來已久,微服務化盛行以後尤其突出。主流的方案有:基於Spring Cloud或者Dubbo等框架。可是這些方案的問題是:1.對代碼有侵入,也就意味着,若是想換框架,得改不少東西。2.語言特異性(Java),若是咱們用的是 Go/Python,或者咱們的微服務不全是 Java,就搞不定了。
Service Mesh
2017 Service Mesh 橫空出世,讓咱們眼前一亮。網上有不少關於 Service Mesh 的介紹,你們能夠去網上搜一搜。個人理解,Service Mesh 的核心思想就是「代理流量」。Service Mesh經過一個個"代理" 來爲微服務轉發/接收全部流量,經過控制這些代理,就能夠實現服務鏈接,註冊,發現,負載均衡,熔斷,監控等等一系列服務治理相關功能,從而微服務的代碼再也不須要服務治理的實現,換句話說,也就是服務治理對於微服務開發者而言是透明的。以下圖所示:綠色方塊爲微服務,藍色方塊爲 service mesh 的代理,藍色線條爲服務間通信。能夠看到藍色的方塊和線條組成了整個網格。這個網絡就是 Service Mesh。
目前廣泛認爲 Service Mesh 有兩代:第一代的 Linkerd/Envoy 和第二代的 Istio/Conduit。第一代相對比較成熟穩定,能夠直接用於生產環境,第二代目前(2018年初)都不完善,嚴重不推薦用於生產。
扇貝的 Service Mesh 是基於 Envoy 配合 Kubernetes 實現的。
這一節以扇貝爲例,簡單介紹下咱們是如何作服務治理的。
首先介紹一些前提:扇貝的微服務所有容器化,編排系統基於 kubernetes
,同步調用基於 gRPC
,異步基於 celery[rabbitmq]
。開發語言以 python3
, nodejs
, go
爲主。 Service Mesh 基於 Envoy
整體的方案是:Envoy
以 DaemonSet
的形式部署到 kubernetes
的每一個 Node
上,採用 Host
網絡模式。 全部的微服務的 Pod
都將 gRPC
的請求發送到所在 Node
的 Envoy
,由 Envoy
來作負載均衡。以下圖所示:
這裏作一些詳細的解釋。
Envoy
中的Route
相似於 Nginx
的 Location
, Cluster
相似於 Nginx
的 upstream
,Endpoint
對應於 Nginx
的 upstream
中的條目。Envoy
而沒有用 Linkerd
,是由於當時 Envoy
是對 HTTP/2
支持最好的。且資源消耗更少。Host
網絡模式是爲了最大化提升性能。Enovy
而言,服務發現就是告訴 Envoy
,每一個 Cluster
背後提供服務的實例的IP(對應於 Kubernetes
也就是 Pod
的IP)是什麼。Kubernetes
的 DNS
,所以,在建立Service
的時候,要使用 ClusterIP: None
。Kubernetes
的 Endpoint
API 實現了 Enovy
的 EDS
(這個項目咱們往後會開源到 GitHub 上)。Envoy
而言,實現熔斷,只要實現 rate limit service 就好了。咱們基於Lyft/ratelimit 實現的 rate limit service。Envoy
的 statistic API反映出來,因此咱們針對 statistic API作服務調用的監控報警。Envoy
的 Access Log 來實現。關於服務治理,咱們接下來的文章還會跟你們分享關於DevOps的實踐, 監控報警系統,日誌系統的構建等等內容。最後,若是你也對微服務,k8s, service mesh, devops 感興趣,歡迎加入!
---
歡迎關注咱們的 知乎專欄:扇貝技術架構小組