從觀望到落地:新浪微博Service Mesh自研實踐全過程

2017年4月25日 Buoyant 公司的 CEO William Morgan 給 Service Mesh 下了個完整的定義,簡言之,“Service Mesh 是一個專用的基礎設施層,用於使服務到服務的通信安全、快速和可靠 … …”,其實更確切的說 Service Mesh 應該誕生於 2016 年,因爲回看很多 Service Mesh 方案早在 2016 年就已經開始摸索前行。隨後的幾年如雨後春筍般出現了很多實現,逐漸形成了其基本事實標準:負責服務間通信的數據面,以及控制整體流量在體系內流轉的控制面。Service Mesh 可謂是當下微服務領域最火的模式。被認爲是下一代的微服務。甚至 2018 年被稱爲 Service Mesh 元年。

本文,我試圖從自己實踐 Service Mesh 過程中的一些感悟出發去探尋 Service Mesh 的本質,希望能給正在關注 Service Mesh 或者計劃實踐、落地 Service Mesh 的你帶來一些我的理解,畢竟大家已經觀望 2 年多,也該考慮落地了。

Service Mesh 到底是什麼?

爲什麼要討論“Service Mesh 到底是什麼?”這樣一個話題,因爲我發現一個有趣的現象,現在大家談論 Service Mesh 時,幾乎就把它與 istio 畫了等號,尤其是越往後關注這個技術方向的人這種情況越明顯。從另一個角度來看,這也算一種技術壟斷,大公司背書的 istio 經過這兩年的發展與其專業的開源運營,幾乎掩蓋了所有其它方案的聲音,讓新進的開發者誤以爲 Service Mesh 就是 istio。這會帶來一個直接的問題: istio 並不一定適應所有的場景。我覺得 Mesh 社區一個同學說的一句話特別有道理“壟斷使得包括其在內的競品並未通過足夠長時間的競爭達到相對的成熟,就過早形成了某種心理意義上的壟斷預期”。導致當下可能很多團隊可能在自己的場景強推 istio,忽視了自己真正的痛點或者假裝自己有 istio 預設那樣的痛點,如此複雜的 istio 體系如果方向選不對,折騰到最後可能吃力不討好。

那麼 Service Mesh 究竟是什麼?

Service Mesh 並不是什麼新的技術,它所關注的問題域比如請求的高效、可靠傳輸,服務發現和治理等有服務化的一天就已經存在。成體系的服務治理方案我們早前很多 SOA、API 網關等就早有深入並已形成標準方法論和行業規範。社區也不乏這方面的最佳實踐。那爲什麼到如今才催生出如此火爆的 Service Mesh?這一切的發生我認爲關鍵點在於兩個方面:首先微服務架構模式成爲大規模分佈式應用的主流架構被大家所熟知與認可;其次雲計算、容器化技術的規模化落地。越來越多的團隊和組織開始實踐微服務。這個時機很重要。

大家很清楚,微服務架構的核心在於基於分而治之理念的服務拆解,而拆解往往使原先可能一次內部方法調用就獲取的結果,轉換爲一次或多次網絡調用,我們都知道網絡本身是不可靠的(這也正是爲何 Service Mesh 解決的核心問題域中始終將請求的可靠傳輸放在至關重要位置的原因),下面我們簡單梳理服務的拆解給我們帶來的挑戰:

  • 拆解後,服務間依賴不可靠的網絡進行通信
  • 缺少一套整體的方案來解決所謂東西向(橫向)服務連通性的問題
  • 如何保證拆解後整體業務的穩定性(一次業務處理可能依賴數目不定的微服務調用)
  • 如何來治理這些拆解後的服務(甚至是異構的微服務體系)
  • 如何規模化、標準化更高效的實施、運維整個微服務體系

過去通常使用微服務治理框架、API 網關等方案來解決上面的問題。比如微博早在 2013 年就開始基於 Motan RPC 框架來解決服務治理的問題,而更早的 API 網關方案也具備相應的服務發現和治理能力甚至比微服務框架出現的還要早。傳統微服務框架通過胖客戶端的方式提供了客戶端實現的服務發現與治理能力。但是這種方式有諸多弊端:

  • 與業務無關的服務治理邏輯與業務代碼強耦合
  • 框架、SDK 的升級與業務代碼強綁定
  • 多語言的胖客戶端支持起來性價比極地
  • 各種語言的服務治理能力天差地別,服務質量體系難以統一

而 API 網關通常部署在集羣的邊緣,作爲業務接入層,雖具備一些通用的服務治理能力,然而其本身的實現相對更重、且往往性能低下,因爲它專注於 API 管理,流經 API 網關的流量都會經過很多通用邏輯,比如鑑權、驗證、路由等,在傳統的 API 網關場景,長達幾十甚至過百毫秒的延遲對南北向的流量來說基本可以接受,但這在處理微服務體系內東西向流量時,這樣的性能是不能容忍的,而且服務的拆分勢必導致整個體系內東西向流量隨着微服務規模的擴大而劇增。所以 API 網關並不能勝任微服務場景下的流量管理任務,它也不是爲此而生的。

再補充一點很多人對 Service Mesh 和 API 網關分不清楚,因爲正好這兩種方案我都經歷過,其實很簡單,它們關注的點不一樣,Mesh 關注內部服務間的互聯互通,核心在於 Sidecar 構建的那張網格以及對應流量及服務的治理,而 API 網關關注的是 API 的管理,雖然它們都有服務治理的能力,但彼此專注的點不一樣。

所以本質上 Service Mesh 的出現就是爲了解決大規模微服務架構下,請求的高效可靠傳輸與服務治理的問題。它將原先實現在微服務框架胖客戶端或者 API 網關接入層的服務治理功能下沉到一個統一的 Sidecar 代理以一個獨立進程的方式部署在業務進程旁邊,通過控制面來保障服務間通信的橫向流量按照業務的真實需求在整個微服務體系內高效流轉,因此 Service Mesh 不是服務治理框架,不是 API 網關更不是 istio。它是一種新興的微服務實施模式。一種微服務治理的標準規範。它有很多種實現,istio 是目前最爲大家所熟知的實現。不過下面我們要看的是微博自研的實現 – WeiboMesh。

WeiboMesh 的理想與現實

瞭解過 WeiboMesh 的同學可能知道,它基於微博早期服務治理 RPC 框架 Motan 演變而來,(沒了解過的同學可以 Google “微博 Service Mesh”,這裏不再贅述)。微博平臺的微服務體系建設做得比較早,平臺內部技術主要是 Java 棧,基於服務治理框架和混合雲有一整套服務化體系。同時平臺還給其它兄弟團隊提供底層數據與存儲資源支撐。數據通過 Restful 接口提供。是一個典型的異構體系服務化整合的場景。隨着平臺微服務規模的增大以及業務複雜度的提高,我們必須面對以下三個難題:

  • 熱點、突發事件所引發流量洪峯(幾倍、十多倍的突增)的應對(要求高效、完備的服務治理體系)
  • 混合雲微服務架構下的複雜拓撲帶來的冗長的調用鏈路、低效的請求長尾與及其複雜的故障排查
  • 各語言服務治理能力差異性引入的異構系統服務治理體系建設難題

爲了應對這些難題,我們摸索了一套 Service Mesh 實現方案。這裏我先對整個方案的幾個核心點做個簡單描述(希望大家能從微博的場景中體會這種方案選取的出發點):

  • 將以往在 Motan RPC 胖客戶端實現的服務發現和治理功能下沉到 Motan-Agent 這個 Sidecar 代理上,通過對服務的訂閱和發現來建立服務間依賴的邏輯網絡,作爲 WeiboMesh 的數據面。
  • 複用 Motan RPC 的 Filter 機制,在 Cluster(服務集羣) 和 Endpoint(節點)兩個維度實現了 Service Mesh 的控制面邏輯,完成對服務間通信流量的管控,作爲 WeiboMesh 的控制面。
  • 服務註冊和發現依賴微博故有的自研 Vintage 命名和配置服務。WeiboMesh 不與任何平臺耦合,可運行在裸機、公 / 私有云、混合雲的場景。
  • 實現全新語言無關的通信協議 Motan2 和跨語言友好的數據序列化協議 Simple 來應對跨語言。通過爲所支持的語言開發標準的 Motan2 客戶端,完成與 Mesh 的通信(對業務較低的侵入性帶來平臺能力的整體輸出,比如我們提供的各種數據服務化、存儲資源服務化能力。這個方案的性價比極高,保證整體架構向前演進而非推倒重來,這在微博大體量的業務需求下顯得格外重要,而且我們跨語言的 SDK 只保留極薄的一層,僅保證使用 Simple 序列化在 Motan2 協議上傳輸請求而已,這很好的控制了整體維護成本)。

這是我們探索了各種跨語言服務化方式後,最終第一版上線時的方案(之前的文章有對此詳盡的描述,請自行 Google,同樣不再贅述),也是一個迄今爲止我們依然認爲比較理想(符合微博現狀)的 Service Mesh 方案。最大程度上覆用了我們多年來在 Java 體系以及混合雲架構下積累的服務化經驗。最大化的保證了平臺技術體系的穩固、高效同時兼顧了極低的接入、升級、維護成本。

爲什麼說理想很豐滿,現實很骨感。整個 WeiboMesh 項目組最初由服務框架組與 Feed 組主導協同多個業務方共建(立項時叫跨語言服務化小組),參與方涉及五、六個團隊,且參與各方都對跨語言服務化有重度需求,一點不誇張的講已經是痛不欲生苦不堪言才逼到這條路上來(經常爲排查一個線上問題,要追蹤無數跳的鏈路,打日誌,加監控,費時費力效果還不理想;四七層的轉發也增大了請求時延;因爲請求雙方服務池的不一致導致跨雲轉發,請求長尾嚴重等)。

所以最初參與的各方,狀態和心境都非常積極,大家很主動的推進整個方案演進、調研、試錯。服務端改造過 GRPC 方案、Yar 方案、Servlet 轉 Motan2 的方案等等,客戶端也改造過很多方案,比如服務在 Client 端的描述、Client 的構造方式、請求的組織形式、各種兜底方案等等。所以第一版上線時,我們其實已經經歷了很多嘗試與磨合。算是比較成功的,我們原型版早在 16 年底就初步線上試水,17 年已經直接抵禦春晚的高峯。

但是往下想把這種理想的方案鋪開來時,現實開始向我們展現出它的骨感。可謂一步一坎:

  • 如何說服項目組外其他各方在新業務上應用 Mesh 方案
  • 如何將老業務接入 Mesh 體系,現有方案 Server、Client 兩端都沒做到完全零侵入
  • Agent 引入的運維複雜度和權責劃分

我們除了需要消除大家對 Mesh 性能和穩定性的顧慮,還要保證方案足夠簡單,避免對已有的運維體系,服務開發、部署模式造成太大的衝擊,同時要讓大家認可 Mesh 改造的收益,用數據和效果說話。

雖然有搜索、微博主站 Page、熱門、話題這樣的一些重量級典型業務方給我們的方案背書,從以往的 Restful 方案接入 Mesh 後,享受到性能提升的同時也收穫了平臺服務治理體系的紅利,因爲有些業務方專注於自己的業務領域,很正常在服務治理及相關體系建設方面會相對薄弱。

對於業務方接入我們的方案已經足夠簡單,只需要多部署一個 Sidecar 代理,將以往的 Restful 調用遷移到我們的跨語言 SDK 上即可,業務方不需要關注 Sidecar 的任何事情,因爲當 Sidecar 出問題時,我們可以退化爲 Restful 調用,並立即報警。

同時我們 Mesh 體系提供了緩存、隊列等服務化資源,通過 SDK 既可以輕鬆訪問,業務方可以由此對自己依賴的服務和資源都有整體治理的能力。對於 SDK 接入這樣的改造,顯然性價比是極高的。然而現實情況是,很多時候可能因爲業務開發壓力等原因,他們並沒有太多的精力來完成這樣的改造。

而另一方面,平臺內部已有的大量老業務如何接入 Mesh 體系?現今平臺業務已經處於一個相對穩定的階段,老業務纔是改造的重中之重,我們必須在 Mesh 體系爲業務方準備好他們依賴的服務。但是 Mesh 方案能爲平臺服務方提供的唯一好處可能就是接入後,他們不再需要同時維護 RPC 和 Restful 兩套服務,但是對於本來就已經歷經風雨穩定運行的平臺服務來說,已有的 Restful 服務沒什麼不好,爲什麼要去改造?顯然大家是不樂意的,雖然我們已經在 Motan RPC 框架層面做了諸多努力,甚至做到只需修改一行配置,多導出一個 Motan2 服務即可,哪有如何?服務端的變更要求非常嚴謹,一行配置同樣需要經過整個上線流程。婉拒的話術通常是諸如“目前業務比較忙,往後有空再具體規劃”此類。

這迫使我們一直在思考一個問題“如果要讓 xxx 接入 Mesh,需要 xxx 做什麼?我們需要支持什麼?”,這也促使 WeiboMesh 迎來了全新的一次演進 – HTTPMesh。HTTPMesh 的目標在於,不需要修改任何一行代碼,真正零侵入接入,具體做法:

  • 將現有 Restful 接口自動導入 Mesh 體系
  • 通過 HTTP_PROXY 將客戶端流量指向 Sidrcax

我們通過解析平臺 Restful 服務對應的 Nginx 配置,將 Restful 接口自動對應到 Mesh 體系的 RPC 服務上,Nginx 的 upstream 與 RPC 的 Service 對應,Restful 服務池與 PRC 服務分組對應,這樣一來原來的 Restful 服務在 Mesh 體系就有了相應的表示。新增業務只需提供一套 Motan2 服務,而非以往的 RPC 和 Restful 兩套。老業務的場景,服務端 Agent 充當反向 HTTP 代理,將進入的 RPC 請求轉換爲 HTTP 請求轉發到之前的 Restful 接口;客戶端我們在 Sidecar 代理上提供了 HTTP 的正向代理支持,通過 HTTP_PROXY 將本地出口的 HTTP 請求都指向 Sidecar,這樣如果 Sidecar 發現請求已經導入 Mesh 體系則會將代理的 HTTP 請求轉換爲 RPC 請求轉發進入 Mesh 網格,否則將 HTTP 請求透傳發出;而新開發的採用了 SDK 方案的服務可以同時享有平臺所有資源、服務及治理體系。這樣雙方接入都不需要做任何改動。

解決了雙方改造成本的大問題,接下來就是引入 Sidecar 對運維流程的影響和權責劃分的問題。在業務進程旁運行 Sidecar 來處理進出流量,需要在固有的運維流程中添加對 Sidecar 的運維,這看似簡單的操作,實則涉及多方面的問題:

  • Mesh 進程與業務進程的啓停(時序、優雅停機)
  • Mesh 進程的升級維護
  • Mesh 進程的監控、報警
  • 故障處理與恢復

運維方面可能各公司情況不一,包括我們內部,不同團隊可能姿勢都不完全一樣,不具有通用性,所以這裏不展開太多,只想說明一點我們爲了應對各種場景和姿勢,我們在 Mesh 上提供了管理端口、後端探測等功能,比如運維可以通過向 Mesh 管理端口發起上下線請求來觸發 Mesh 自動上下線服務,也可以通過配置探測地址及狀態來對業務進程進行健康檢查指導該節點上下線或告警,另外我們提供了多種發佈方式,鏡像、RPM 包等一應俱全,便於運維挑選適合自己生產的部署方式,我們還將 Mesh 配置做了統一的管理,因爲以往接入的經驗來看,80% 場景使用通用配置即可,只有很少的 20%,甚至更少的場景需要個性化配置,那樣也減少大家理解和我們作爲方案提供方的指導成本。所有 Mesh 相關的包、庫和配置都由我們提供,這樣也有了明晰的權責劃分,我們爲 Mesh 負責,降低業務方的心智負擔。

就這樣,我們在 WeiboMesh 的路上繼續前行。因爲我們深知微服務、雲計算纔是穩定服務的正道。確實給我們帶來了很多現實收益,而且我們相信這些收益仍在不斷放大。

如何落地 Service Mesh

前面我們探討了 Service Mesh 的本質,分享了一些 WeiboMesh 實踐過程中的經驗,下面我們來討論下如何落地 Service Mesh。

Service Mesh 很好的解決了規模化微服務架構下服務通信和治理的問題,給我們帶來了很多確確實實的好處,網絡上相關的解讀很多了我就不再次囉嗦。這裏我只想根據自己的實踐和理解,梳理出一些我認爲很適合引入 Service Mesh 的場景,希望能幫助大家更好的做出判斷:

  • 還未進行任何形式服務化;有的初創團隊可能先期並沒有太多精力來進行技術建設,但是技術的穩定性是業務增長的基石,Service Mesh 的整套的微服務治理方案正好是個不錯的選擇,先期可能不需要對服務做太細粒度的拆分,可以基於 Mesh 體系來構建,逐步接入、分解
  • 有跨語言互通的需求;這不用多說,前面分享的 WeiboMesh 就是這方面的實踐的好例子
  • 內部服務依賴重(東西向流量);有些業務可能同時依賴很多服務,一次請求對應數次 Restful 請求,有繁重的網絡 I/O 需要處理,可以引入 Service Mesh 來保障這些請求的可靠性
  • 依賴傳統的服務化框架做服務治理;這裏主要指服務治理與業務邏輯強耦合的場景,前面也討論過這種方案的各種弊端,引入 Service Mesh 將服務治理邏輯與業務邏輯解耦,應用開發的同學只需專注自己的業務,這是最好的選擇
  • 技術建設與前瞻性;雲計算與微服務爲提高服務構建效率、降低投入成本提供了可能性,這裏面的想象空間是巨大的,從大廠在此方面的投入可見一斑,俗話說的好,錢在哪兒方向就在哪兒。具有前瞻性的技術儲備將爲組織迎接各種挑戰提供堅實後盾

想清楚我們確實需要落地 Service Mesh,認可其帶來的巨大收益,剩下的就是 Service Mesh 方案的選擇了。我們需要制定一個可執行的 Service Mesh 實施方案。還是那個老生常談的話題:“選擇自研、開源還是基於開源微創新?”。在這方面我只有一條建議:“因地制宜,不盲目跟風”。選擇的過程中,頭腦一定要清晰,仔細分析自己的場景和業務痛點,調研與自己場景最貼合的開源方案,過程中掂量自己可支配的資源以及項目週期同時關注方案複雜度。儘量避免重複造輪子。

不過事實上開源方案一般考慮比較通用的場景,很難有能與自己場景完全吻合。這時候爲了控制成本更多會選擇基於開源進行改造。這就引入了一個與開源共建的問題。應該避免獨立 fork 導致後期離開源越走越遠。

Service Mesh 從出現到現在兩年多的時間裏可謂發展迅猛,這離不開社區大家的熱情,拋開大廠在前面帶風向不說,技術本身確實有很多先進性,不管是否入坑 Service Mesh,作爲一個工程師我覺得都應該深入瞭解,學習這種 Mesh 思考模式和工程化、標準化思路。希望本文能給你帶來一些思考。


作者簡介

周晶,新浪微博平臺研發技術專家,負責微博跨語言微服化框架開發以及 ServiceMesh 技術落地等,OpenResty 社區委員會成員,高性能 OpenResty 開發框架 Vanilla 作者,開源愛好者,關注微服務、雲原生等技術。此外,周晶將在QCon廣州站爲大家分享微博 Service Mesh 實踐。大會目前8 折報名福利,立減 1360 元,諮詢可致電魚丸:13269078023(微信同號)。

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