Service Mesh 是近兩年比較火的微服務化新方式,也產生了一大批以 Istio 爲表明的 Service Mesh 實現。php
微博基於實際業務需求,打造並開源了本身的 Weibo Mesh,而且內部已經在重點業務上進行大規模落地。網絡
本文將從以下幾個部分爲你們詳細解讀 Weibo Mesh,但願能夠爲你們帶來服務化方向上的一些靈感,更好的服務於本身的業務:架構
微博服務化挑戰負載均衡
服務化新思路框架
Weibo Mesh 方案介紹運維
生產實踐ide
總結模塊化
微博服務化挑戰函數
首先,爲你們介紹下微博服務化面臨的挑戰。微博的形態比較特殊,除去常態午/晚高峯流量較高外,突發熱點事件的殺傷力更大。微服務
熱點事件來襲時,流量極短期內呈現爆炸式增加,而且每每事件爆發沒有任何徵兆。這對於微博服務化及穩定性均帶來了極大挑戰。
若是其中某一個環節掉鏈子,不能及時感知並做出應對,極有可能會致使雪崩式宕機,致使全站掛掉。
那麼怎麼解決這種問題呢?首先會想到自動擴縮容/降級建設,可是咱們決策依賴是什麼呢?又如何知足系統可觀測性要求,以及如何評價系統可用性及冗餘度呢?
究其本質,系統的服務治理建設很是重要,它會直接影響到服務可用性。可是微博技術棧的多樣性又致使了在微服務化和服務治理方面困難重重。
從技術層面看,微博的典型服務調用大體如上圖,業務體系會調用平臺體系的多個接口,例如經過平臺接口獲取微博內容。
平臺體系主要是 Java 技術棧,原本微服務相關解決方案也多,再加上服務化時間較早,平臺微服務體系建設相對比較完善,同時也產出了一些優秀開源框架,好比 Motan 微服務框架。
業務方的語言棧:多樣化,基本涵蓋了全部主流語言,其中 PHP 相關係統流量佔比較大。
調用鏈路:一般狀況下業務方和平臺使用 RestFul API 進行交互。一次請求調用要通過 4,7 層的層層調度,服務穩定性還時常遭受網絡抖動及 DNS 不穩定的困擾,在中間層的消耗是不容忽視的。
另外,業務部門的語言種類繁多,間接致使了各部門微服務體系建設良莠不齊。
峯值流量應對須要全部部門全部業務模塊的通力協助和聯動,考驗的是整站實力,咱們須要全部模塊都能具有高水平的服務治理能力。所以咱們迫切須要解決跨語言微服務化問題。
上圖是微博平臺內部的微服務體系支撐圖,平臺實現以 Motan 框架爲核心的微服務治理體系 。
此外,還有自研的 Vintage 註冊中心及 Open DCP 智能彈性調度平臺以及 Graphite 實時監控平臺,能夠看出平臺微服務架構有完善的 DevOps 支撐。
業界的大趨勢是雲原生,微服務做爲雲原生重要的一環,是咱們必需要突破的。
微博服務化新思路
跨語言服務治理嘗試
爲了解決跨語言服務治理的問題,我簡單介紹一下咱們嘗試過哪些解決方案。
這裏有個大背景,Motan 因爲是微博內部使用已久,經歷太重大考驗而且開源的優秀框架,它積累了不少優秀的服務治理經驗,因此咱們服務化改造要充分考慮 Motan 的存在。
咱們嘗試將 Motan 適配 Yar 這種 PHP 的 RPC 協議,PHP 能夠與 Server 端的 Java 進行通信,但 PHP 並不能進行服務發現。
因而咱們在 PHP 旁邊加一個 Daemon 程序,也考慮過使用 Nginx,來作服務發現。
固然問題也是顯而易見的,這樣改造會致使業務侵入變高,成本變大,擴展性也較差,況且並無解決 PHP 作 Server 端的服務治理問題。
咱們也嘗試過 GRPC,固然跨語言調用能解決,可是這裏遇到幾個問題,一個是如何進行服務治理,另一個是 PB 序列化問題。
因爲微博場景的內容結構體很是大,效率並不比 Json 高,業務變動致使 PB 文件的變動讓升級維護成本變得難以接受,另外序列化數據遇到問題調試也變的困難。
此外 ,技術棧的多樣性也會引起一系列的問題。即便咱們解決了 PHP 到 Java 的調用問題。可是相同的治理功能,不一樣的語言不可能再實現一遍。
Motan 框架積累下來的服務治理經驗是咱們須要傳承和發揚的,那如何均衡這些問題及解決方案呢?
跨語言服務化本質
我認爲跨語言服務化的本質,總結下來有兩點:
數據交互
服務治理
數據交互設計要考慮跨語言及協議中立,服務治理設計要靈活全面且可擴展。
上圖我列舉了跨語言服務化方式的優缺點:
傳統的 HTTP 代理,能夠解決不一樣服務之間的調用。HTTP 就是傳統的走網關,較容易實現,但由於內部的調用每一個人都要加網關,這就增長了鏈路,致使擴展能力低。
RPC 模塊或者 Agent 代理。RPC 框架業界有不少,大多 Java 棧的,功能也齊全,但跨語言維護成本很是之高。
Agent 代理是一個新的思路,Agent 代理的研發成本、維護成本、使用成本對比起來均比較折中,即咱們獨立一個 Agent 來專門解決咱們遇到的跨語言服務化困擾。
那樣既能釋放傳統的業務端的服務治理壓力,又能傳承 Motan 框架的精髓,也不須要實現多語言服務治理邏輯,更可讓業務和 Agent 互相獨立發展,可謂一舉多得。
這個思路最終也演化成了今天的 Weibo Mesh:
由此微博走向了 Service Mesh。微博走向 Service Mesh,並非盲目追趕最新的技術潮流。
咱們立足於現狀,立足於解決實際業務問題,並一步步探索事後,發現最終的解決方案與 Service Mesh 思路不謀而合。從側面也驗證了 Service Mesh 思路解決服務化問題的合理性和前瞻性。
上圖,咱們能夠用正交分解法來理解 Service Mesh,能夠看到,原有的微服務被拆分紅業務邏輯層和服務交互治理層,其中服務交互治理層抽象爲 Service Mesh。
Service Mesh 把服務間的交互與治理邏輯從業務中進行解耦,抽象獨立成一個專門的處理模塊。
一般 Mesh Agent 以 Sidecar 的形式和業務進行本機部署,Agent(如下 Mesh Agent 簡稱 Mesh 或 Agent)能夠理解爲服務的基礎設施層,業務無需關心服務間交互/治理細節,所有交由 Agent 統一處理。
Service Mesh 帶來的是微服務架構思路的轉變,爲業務開發帶來了諸多架構上的優點,Agent 及業務都可獨立發展,一般 Agent 交由運維管理,業務開發交由業務線,故總體能夠作到持續開發、持續集成。
Mesh 思路不光能夠解決跨語言服務化的問題,也能夠解決資源服務化問題,而這些改造基本都對業務方透明。
Weibo Mesh 方案介紹
下面具體介紹下 Weibo Mesh 的實現方案。上圖是 Weibo Mesh 架構圖,除了必須的 Mesh Agent 外,考慮到業務遷移及實際落地須要,這裏在業務代碼和 Mesh 之間增長了 Client。
這個 Client 很是輕,其核心功能是封裝 Mesh 請求,方便業務進行 Mesh 調用,最大限度下降業務遷移成本。
實際上在 Client 中咱們也實現了其餘一些對業務友好的功能,同時對 Mesh 調用進行了功能加強。
好比能夠在 Client 中進行跨語言的序列化,Mesh 故障轉移,請求多發,超時控制等。
固然不一樣業務方能夠進行功能定製。Client 和業務相同的語言編寫,其核心目的是幫助業務進行平滑遷移。
Mesh 層實現了 Service Mesh 的核心功能,包括髮現、交互、路由、治理。
Weibo Mesh 是由 Go 實現的,國內各大廠商的 Mesh 數據平面也大多使用 Go 來實現。
Go 具備優秀的性能及易用性,又是雲時代比較推崇的語言,將來 Mesh 層極有可能結合容器,沉澱成爲容器的一個基礎設施層。
Weibo Mesh 數據面
剖析一個 Service Mesh 服務,通常經過數據面和控制面。首先來看一下 Weibo Mesh 在數據平面的表現,包含五個核心模塊:
Cluster(集羣管理),對分組下經過服務發現回來的的節點列表的抽象管理。
HA(高可用策略)、LB(負載均衡)。
Endpoint(服務節點的抽象),本質上是 IP 和端口,但從代碼層面看,它是服務節點的抽象,經過 Endpoint 能夠進行直接的調用,能夠理解爲它是調用的一個單元。
Protocol(Motan2/傳輸協議+Simple/序列化協議)。
下面一一介紹這些模塊。
①Cluster 模塊
調用方請求經過本機的 Mesh,在 Cluster 模塊處理中,首先通過一系列集羣粒度的 Filter Chain(過濾鏈,包含集羣 Metric,熔斷,攔截,鑑權,分組切換等功能,它們以鏈式結構進行組織調用,支持任意過濾功能擴展)。
而後再通過高可用策略跟負載均衡策略篩選出一個可用的 Endpoint,在 Endpoint 中又會進行請求粒度的 Filter Chain(單機的日誌記錄,Metric 等),經過進行請求序列化,根據傳輸協議進行組裝,最終經過 Endpoint 把請求發到對端的 Mesh 上。
②高可用策略
Weibo Mesh 中的高可用策略,支持通常的經常使用策略,好比 Failfast,Failover 等,負載均衡支持權重輪巡,根據權重輪巡、隨機等經常使用策略。固然也能夠定製本身的 HA/LB 策略。
Weibo Mesh 中推薦採用的高可用策略是 Backup Request,又叫雙發。雙發繼承自 Motan 框架,是咱們探索出來的比較高效可靠的機制。它能夠有效解決長尾問題,同時能提高系統吞吐量。
傳統解決接口超時問題可能經過重試,在一次請求發送以後等待指定的超時時間,若是沒有返回則再請求一次,最差狀況下要消耗 2 倍的超時時間。
而雙發機制則否則,在發送一次請求後等待 P90(在 T1 時間內有 90% 的請求都能返回則稱 P90=T1,一般系統的 P90 和程序設置的超時時間相比小不少)時間。
若是請求沒有返回則在此刻再次發送一次請求,在超時時間內,這兩個請求中取最快返回的那個。
固然,這裏有個防雪崩機制,假如,超過必定數量的請求(好比 15%)都在進行雙發,則認爲服務總體有問題,會自動中止雙發。實踐證實,雙發機制的去長尾效果很是明顯。
③節點抽象
Endpoint 是調用方 Mesh 到對端 Mesh 的調用單元。當咱們啓動 Weibo Mesh,在初始化 Cluster 的同時,也會對 Endpoint 進行初始化,綁定 Filter Chain,併爲每一個 Endpoint 保持必定數量的長連接供選擇調用。
固然這裏還會有一些細節,若是某個節點的調用失敗,計數超過必定閾值則自動摘除節點,並進行按期探測等待可用,再從新加入可用節點列表。
④Motan2 傳輸協議
Weibo Mesh 總體沿用了 Motan 的協議設計,並進行了升級。
Motan 支持 Java 的序列化,當時考慮的是 Java 間相互通訊,可是考慮到跨語言通訊及將來擴展須要,咱們把協議設計分紅序列化協議與傳輸協議。傳輸協議負責把序列化後的數據進行傳輸,序列化協議是跨語言的關鍵。
Motan 傳輸協議是典型的三段式:
Header
Metadata
Body
Header 中會標記序列化類型,消息類型(心跳仍是正常請求),能夠定義本身的 PB 序列化或是自研的 Simple 序列化。
在 Metadata 中會有一些方法名、屬性名、用戶參數;在 Body 中存放的是通過序列化後的請求/響應體。
Simple 序列化:Simple 設計比較簡單實用。目前 Simple 序列化支持了基礎類型,包括 Bool、String、Int、Float,固然它還會支持一些組合類型,例如 String、Bool 組合成的 Map,Array 等。
上圖示例,type 是一個字節的數據類型,好比 Bool、String,接下來是字節長度,接下來是 UTF-8 字節流。Content 中能夠進行嵌套,下方就是進行嵌套的例子。
協議轉換過程:從協議層面看 Weibo Mesh 請求流轉是調用方經過函數調用 Client,而後通過 Motan2 傳輸協議以及 Simple 序列化後,通過本機 Mesh,Mesh 層再轉發給對端的 Mesh。
對端 Mesh 上層多是任意一種形式的服務,好比非 RPC 服務,因此這裏咱們有個 Provider 模塊,能夠代理 HTTP/CGI 等非標準 Service Mesh 服務,它能把這些服務導出成一個具備 Motan 協議的 RPC 服務。
經過 Provider 屏蔽了 Server 端服務的真實協議。Provider 外面是標準的 Motan 協議服務,內部是原有協議的服務,這樣對 Server 端來講,遷移到 Weibo Mesh 成本極低。
Weibo Mesh 控制面
控制面主要分兩方面:
①策略擴展
Cluster 和 Endpoint 都有相應的 Filter Chain,他們實現了不一樣緯度或者粒度的調用控制策略。
Filter Chain 包括訪問日誌記錄、Metric、熔斷、限流、降級等。折中調用效率和耦合程度,它們都是以插件形式存在於 Weibo Mesh 中,也能夠自由定製 Filter 策略及調用順序。
②流量調度
Weibo Mesh 的流量調度基於註冊中心。註冊中心不只爲 Mesh 提供了服務的註冊和發現,也提供了服務的配置下發,Mesh 在訂閱註冊中心的同時,也須要訂閱相關的配置項。
好比咱們把 A 機房的流量都路由到 B 機房去,咱們在 Mesh 只要支持這條指令就能夠。
生產實踐
典型場景
上圖是網關,Mesh 在微服務架構中的總體分佈圖。通常狀況下網關架設在服務邊緣,邊緣節點主要把控宏觀的流量調度控制問題。
在內部,各微服務之間構建 Weibo Mesh,來有效提升服務間通訊質量、可觀測性等要求。
遷移成本的考量:
真正將 Service Mesh 引入到業務場景中時,須要考慮一些問題點,好比業務部署模式是非雲,混合雲仍是雲原生?像微博是混合雲,場景不一樣,所以架構也不盡相同。
Weibo Mesh 要適配註冊中心。
各語言要適配 Client,目前已經支持 PHP/C++/C/Python/Lua 等主流語言,Java/Go 原生支持。
要適配相應的 DevOps 建設。須要相應的監控/統計等平臺支撐,任何架構改造都要有足夠的 DevOps 支撐。
接下來爲你們介紹 Weibo Mesh 正反向代理實踐。
正向 Mesh
上圖是 Weibo Mesh 場景下的正向代理流程。Server 端服務進行註冊,被調用方訂閱到,調用方請求通過 Client,再通過本機 Mesh,最終到對端的 Mesh。須要注意的是虛線部分是故障轉移的流程。
假如本機 Mesh Agent 掛掉,Client 會經過服務發現回來的節點快照選擇可用節點進行調用,達到故障轉移的目的。
反向 Mesh
上圖是 Weibo Mesh 場景下的反向代理流程。通常咱們的服務類型是 HTTP/CGI,或者其餘私有協議。
反向 Mesh 的亮點在於,不須要 Server 端作任何架構的改造,直接架 Weibo Mesh 就能夠了。
Mesh Agent 經過 Provider,將原有協議導出成 Motan2 協議的服務對外進行暴露,只須要把導出的服務註冊到註冊中心便可提供服務。
同時也不會影響原有服務的提供。這裏若是你須要把私有協議導出成 Motan2 協議服務,能夠自行擴展開發。默認支持 http/php-cgi 服務的導出。
反向 Mesh 特點:
提供 HTTP/cgi provider,可定製擴展。
HTTP 框架自動轉 RPC,業務無需開發新 RPC 框架。
Mesh 對 Server 改造無侵入。
總結
治理模式的差別
傳統服務調用,中間可能通過網關或者 RPC。服務治理只能存在於一端,通常在 Server 端進行服務治理。
可是 Mesh 服務,因爲 Agent 本機部署,封裝了服務治理,能夠實現 Client 端或 Server 端的雙向治理,這是 Mesh 服務的一大特點。
Weibo Mesh 優點
實戰效果以下圖:
上圖能夠看到,Mesh 服務的 Client 端 RT 曲線逼近 Server 端的 RT,這說明點對點的 Mesh 調用,因爲沒有中間層的損耗,再加上合適服務治理手段,兩端性能也比較接近。而 HTTP 服務則有較多的中間層損耗。
右圖能夠看到雙發的 p999 曲線相對比較直,這說明雙發起到有效削長尾功能,間接也對系統性能有提高。
Weibo Mesh 集羣
目前,微博內幾個核心業務之間調用已經 Mesh 化,並經歷太重大事件以及春晚的考驗,支撐流量仍是至關大的。
和 Istio 的區別
從控制層面看,Weibo Mesh 把相似 Istio 中的 Mixer 和 CA 的功能以插件化的形式放到 Filters 裏面。
Istio 服務須要經過 Pilot 來作服務發現,而 Weibo Mesh 是直接經過註冊中心,Istio 用 Envoy 作 Sidecar,而咱們基於 Motan 打造了全新的 Agent。
Istio 有一個特點,上面每一個模塊均可以理解爲一個微服務,均可獨立拆分部署。
可是 Weibo Mesh 爲了效率和內部落地的方便,更多的進行了插件式耦合,總體性能相比 Istio 也會更好。
上圖能夠看到 Istio 經過雲平臺適配各類 API,來進行服務發現,Weibo Mesh 則是適配註冊中心。
Istio 更強調依據容器層面的發現(直奔雲原生),Weibo Mesh 則可支持通用註冊中心好比 Consul、ZK 等。
Weibo Mesh 經過 Client 攔截 Mesh 請求,模塊化耦合部分功能。高定製化時,並不能對服務作到徹底透明。而 Istio 經過 IPtables 流量攔截實現了業務徹底無感知。
WM 進行中
咱們知道 Mesh Agent 並不關心代理轉發的是什麼服務,因此就有一個新方向,即資源服務化,讓資源存儲層也能進行服務化。
Weibo Mesh 解決跨語言服務化的思路也一樣適用於服務與資源之間的調用問題。微博服務有不少資源依賴,MC、Redis、MySQL、MCQ 等。
咱們能夠在資源層架設 Agent,一樣能夠達到資源即服務,也就是泛服務化。目前咱們內部也已經有基於 Weibo Mesh 的資源服務化使用場景。
WM 將來發展方向
將來 Weibo Mesh 主要有兩個方向,一個是繼續推動雲原生,一個是在易用性方面繼續打磨。
Weibo Mesh 打通雲平臺和註冊中心推動雲原生,結合容器編排在服務治理上進行優點互補。
此外,咱們也會積極努力推動,讓 Mesh 整合進 L5 這一層。咱們還會繼續進行探索解決業務方接入不方便的地方,好比說更加方便的流量攔截方式;更普遍的語言支持…
Weibo Mesh 始終推崇落地簡單、功能高效可靠,隨着 Mesh 更大規模的推廣,場景愈來愈極端,性能要求愈來愈高,咱們在這方面也會持續打磨。歡迎你們一塊兒加入 Weibo Mesh!