導讀
在私有云集羣環境下建設 Service Mesh ,每每須要對現有技術架構作較大範圍的改造,同時會面臨諸如兼容困難、規模化支撐技術挑戰大、推廣困境多等一系列複雜性問題。本文會系統性地講解在美團在落地 Service Mesh 過程當中,咱們面臨的一些挑戰及實踐經驗,但願能對你們有所啓發或者幫助。html
1、美團服務治理建設進展
1.1 服務治理髮展史
首先講一下 OCTO,此前美團技術團隊公衆號也分享過很相關的文章,它是美團標準化的服務治理基礎設施,現應用於美團全部事業線。OCTO 的治理生態很是豐富,性能及易用性表現也很優異,可總體歸納爲 3 個特徵:算法
- 屬於公司級的標準化基礎設施。技術棧高度統一,覆蓋了公司 90% 以上的應用,日均調用量達數萬億次。
- 經歷過較大規模的技術考驗。覆蓋數萬個服務、數十萬個節點。
- 治理能力豐富。協同周邊治理生態,實現了 SET 化、鏈路級複雜路由、全鏈路壓測、鑑權加密、限流熔斷等治理能力。
回顧美團服務治理體系的發展史,歷程總體上劃分爲四個階段:緩存
- 第一階段是基礎治理能力統一。實現通訊框架及註冊中心的統一,由統一的治理平臺支撐節點管理、流量管理、監控預警等運營能力。
- 第二階段重點提高性能及易用性。4 核 4GB 環境下使用 1KB 數據進行 echo 測試,QPS 從 2 萬提高至接近 10 萬,99 分位線 1ms;也建設了分佈式鏈路追蹤、分階段耗時精細埋點等功能。
- 第三階段是全方位豐富治理能力。落地了全鏈路壓測平臺、性能診斷優化平臺、穩定性保障平臺、鑑權加密等一系列平臺,也實現了鏈路級別的流量治理,如全鏈路灰度發佈等。
- 第四階段是建設了跨地域的容災及擴展能力。在天天數千萬訂單量級下實現了單元化,也實現了全部 PaaS 層組件及核心存儲系統的打通。
![](http://static.javashuo.com/static/loading.gif)
1.2 服務治理體系的困境
目前,美團已具有了較完善的治理體系,但仍有較多的痛點及挑戰。大的背景是公司業務蓬勃發展,業務愈發多元化,治理也愈發精細化,這帶來了較多新的問題:性能優化
- 業務與中間件強耦合,制約彼此迭代。當中間件引入 Bug,可能成百上千、甚至數千個業務須要作配合升級,中間件的新特性也依賴業務升級後才能使用,成本很高。
- 中間件版本碎片化嚴重。發佈出去的組件基本託管在業務側,很難統一進行管控,這也頻繁形成業務多類的問題。
- 異構體系融合難。新融入公司的技術體系每每與美團不兼容,治理體系打通的成本很高,難度也很大。此前,美團與大衆點評打通治理,不包含業務遷移,就歷時 1 年半的時間;近期,摩拜使用的 gRPC 框架也沒法與系統進行通訊,但打通迫在眉睫。
- 非 Java 語言治理體系能力弱,多個主流語言無官方 SDK。多元業務場景下,將來多語言也是個趨勢,好比在機器學習領域,Python 語言不太可能被其餘語言徹底代替。
2、服務治理體系優化的思路與挑戰
2.1 優化思路
總結來看,OCTO 在服務層實現了統一抽象來支撐業務發展,但它並未解決這層架構能夠獨立演進的問題。微信
1.2節中問題1與問題2的本質是「耦合」,問題3與問題4的本質是「缺少標準服務治理運行時」。在理想的架構中,異構語言、異構治理體系能夠共用統一的標準治理運行時,僅在業務使用的 SDK 部分有輕微差別。網絡
因此,咱們總體的優化思路分爲三步:隔離解耦,在隔離出的基礎設施層建設標準化治理運行時,標準之上建體系。架構
![](http://static.javashuo.com/static/loading.gif)
上述解決方案所對應的新架構模式下,各業務進程會附屬一個 Proxy 進程,SDK 發出以及接收的流量均會被附屬的 Proxy 攔截。像限流、路由等治理功能均由 Proxy 和中心化的控制大腦完成,並由控制面對接全部治理子系統集成。這種模式下 SDK 很輕薄,異構的語言、異構的治理體系就很容易互通,從而實現了物理解耦,業界將這種模式稱爲 Service Mesh(其中 Proxy 被稱爲數據面、中心化控制大腦被稱爲控制面)。併發
![](http://static.javashuo.com/static/loading.gif)
2.2 複雜性挑戰
美團在實踐中所面臨的複雜性劃主要包括如下4類:框架
- 兼容性:技術改造涉及範圍較大,一方面須要經過保證現有通訊方式及平臺使用方式不變,從而來保障業務研發效率,另外一方面也要解決運行載體多樣性、運維體系兼容等問題。
- 異構性:第一是多語言互通問題;第二是打通治理體系內的衆多治理子系統,像服務鑑權、註冊中心等系統的存儲及發佈訂閱機制都是不一樣的;第三是快速打通新融入公司的異構治理體系。
- 大規模支撐:出於性能方面考慮,開源 Istio 等產品不宜直接應用於大規模的生產環境,美團控制面需具有百萬級連接下高吞吐、低延遲、高精確的系統能力。
- 重交易型業務容錯性低:交易型業務場景下,業務對 Service Mesh 的性能、穩定性每每持懷疑態度;美團基礎架構團隊也強調在業務價值導向下,基於實際業務價值進行運營推廣,而不是採用從上至下的偏政策性推廣方式。
3、美團落地 Service Mesh 的解決方案
3.1 總體架構
美團採用數據面基於 Envoy 二次開發、控制面自研爲主、SDK 協同升級的方案(內部項目名是 OCTO Mesh )。架構簡介以下:運維
- 各語言輕薄的 SDK 與 Proxy 經過 UDS(Unix Domain Socket)交互,主要出發點是考慮到相比透明流量劫持,UDS 性能與可運維性更好。
- 控制面與 Proxy 經過雙向流通訊,控制面與治理生態的多個子系統交互,並將計算處理過的治理數據及策略數據下發給 Proxy 執行,協同配合完成路由、限流等全部核心治理功能。
控制面內部的 5 個模塊都是自研的獨立服務。
- Pilot 承載核心治理能力,與 Proxy 直接交互。
- Dispatcher 負責屏蔽異構子系統差別。
- 集中式健康檢查管理節點狀態。
- Config Server 管理 Mesh 體系內相關的策略,並將 Pilot 有狀態的部分儘可能遷移出來。
- 監控及巡檢系統負責提高穩定性。
- 自研了的 Meta Server 系統實現 Mesh 體系內部的節點註冊和尋址,經過管理控制面與數據面的連接關係,也實現了按事業羣隔離、水平擴展等能力。
![](http://static.javashuo.com/static/loading.gif)
3.2 兼容性解決方案
兼容性的目標及特徵用一句話來總結就是:業務接入無感知。爲此,咱們作了如下三件事情:
(1) 與現有基礎設施及治理體系兼容
- 將 Service Mesh 與 OCTO 深度打通,確保各治理子系統的使用方式都不變。
- 運行載體方面,同時支持容器、虛擬機、物理機。
- 打通運維體系,保證服務治理基礎設施處於可管理、可監測的狀態。
(2) 協議兼容
- 服務間調用每每是多對多的關係,通常調用端與服務端沒法同時升級,爲支持 Mesh 與非 Mesh 的互通,加強後的協議對業務徹底透明。
- 與語義相關的全部內容(好比異常等),均在 SDK 與 Proxy 之間達成共識,保證兼容。
- 沒法在控制面及數據面中實現的能力,在 SDK 中執行並經過上下文傳遞給 Proxy,保障功能徹底對齊,固然這種狀況應該儘可能避免的。
(3) Mesh 與非 Mesh 模式的無縫切換
- 基於 UDS 通訊必然須要業務升級一次 SDK 版本,咱們在 2020 年初時預先發布早作部署,確保當前大部分業務已經升級到新版本,但默認還是不開啓 Mesh 的狀態。
- 在可視化平臺上面經過開關操做,幾乎無成本實現從 Mesh 模式與非 Mesh 模式的切換,並具有實時生效的能力。
3.3 異構性解決方案
異構性的目標及特徵用一句話總結就是:標準化服務治理運行時。具體可拆分爲3個子目標:
- 標準化美團內部 6 種語言的治理體系。
- 架構層面由控制面統一對接各個治理子系統,屏蔽註冊中心、鑑權、限流等系統具體實現機制的異構性。
- 支持摩拜及將來新融入公司的異構治理體系與公司總體的快速融合。
針對上述3個子目標,咱們所採起的方案以下:
- 將數據面 + 控制面定義爲標準化的服務治理運行時,在標準運行時內打通全部治理能力。
- 建設統一接入中心繫統 Dispatcher ,並由其對接並屏蔽治理子系統的異構性,從而實現外部系統的差別對 Pilot 透明;下圖中 Dispatcher 與 Pilot 直接交互,Meta Server 的做用是避免廣播下降冗餘。
- 重構或從零建設 SDK,目前使用的 6 種語言 SDK 均已落地並使用。
- 異構語言、異構體系均使用加強的統一協議交互,實現互通。
![](http://static.javashuo.com/static/loading.gif)
經過 Service Mesh 實現體系融合的先後對好比下:
- 引入 Service Mesh 前,單車向公司的流量以及公司向單車的流量,均是由中間的 adaptor 單點服務承接。除穩定性有較大隱患外,全部交互邏輯均須要開發兩份代碼,效率較差。
- 引入 Service Mesh後,在一套服務治理設施內打通並直接交互,消除了中心 adaptor 帶來的穩定性及研發效率方面的缺陷;此外整個打通在1個月內完成,異構體系融合效率很高。
![](http://static.javashuo.com/static/loading.gif)
經過上述方案,針對異構性方面取得了較好的效果:
- 標準化 6 種語言治理體系,非 Java 語言的核心治理能力基本對齊 Java;新語言也很容易融入,提供的官方 Python 語言、Golang 語言的通訊框架新版本(依託於 OCTO Mesh),開發成本均控制在1個月左右。
- 支持異構治理子系統經過統一接入中心快速融入,架構簡潔、擴展性強。
- 支持異構治理體系快速融合並在單車側落地,異構治理體系打通成本也從 1.5 年下降到 1 個月。
3.4 規模化解決方案
3.4.1 開源 Istio 問題分析
規模化的目標及特徵用一句話總結是:具有支撐數萬服務、百萬節點體量的系統能力,並支持水平擴展。挑戰主要有3個:
- 美團體量是最流行開源產品 Istio 上限的上千倍。
- 極高的實時性、準確性要求;配置下發錯誤或丟失會直接引起流量異常。
- 起步較早,業界參考信息不多。
通過對 Istio 架構進行深刻分析,咱們發現核心問題聚焦在如下3個瓶頸點:
- 每一個控制面實例有 ETCD 存儲系統的所有數據,沒法水平擴展。
- 每一個 Proxy 連接至關於獨立與 ETCD 交互,而同一個服務的 Proxy 請求內容都相同,獨立交互有大量的 I/O 冗餘。當 Proxy 批量發版或網絡抖動時,瞬時風暴很容易壓垮控制面及 ETCD。
- 每一個節點都會探活全部其餘節點。10 萬節點規模的集羣,1 個檢測週期有 100 億次探活,會引起網絡風暴。
![](http://static.javashuo.com/static/loading.gif)
3.4.2 措施一:橫向數據分片
針對 Istio 控制面各實例承載全集羣數據的問題,對應的措施是經過橫向邏輯數據分片支持擴展性,具體方案設計以下:
- Proxy 啓動時會去向 Meta Server 系統請求須要鏈接的 Pilot IP,Meta Server 將相同服務的 Proxy 儘可能落到同一個控制面節點(內部策略更爲複雜,還要考慮地域、負載等狀況),這樣每一個 Pilot 實例按需加載而沒必要承載全部數據。
- 控制面節點異常或發佈更新時,其所管理的 Proxy 也會有規律的遷移,恢復後在必定時間後還會接管其負責的 Proxy,從而實現了會話粘滯,也就實現邏輯上面的數據分片。
![](http://static.javashuo.com/static/loading.gif)
經過管理連接關係實現了按事業羣隔離、按服務灰度等平臺能力,最關鍵的仍是解決了 Mesh 體系水平擴展的問題。
3.4.3 措施二:縱向分層訂閱
針對 Istio 獨立管理各 Proxy 連接的 I/O 冗餘問題,對應的措施是經過分層訂閱減小冗餘 I/O。Proxy 不直接與存儲等系統對接,而是在中間通過一系列的處理,關鍵點有兩個:
- 關鍵點 1:基於快照緩存 + 索引的機制來減小 ZK watcher 同步。以註冊中心爲例,常規實現方式下,若是每一個 Proxy 關注 100 個節點,1 萬個節點就會註冊 100 萬個 watcher,相同服務的 Proxy 所關注內容是相同的,另外不一樣服務 Proxy 所關注的也有不少交集,其中包含大量的冗餘。分層訂閱模式下,Proxy 不與註冊中心直接交互,經過中間的快照緩存與分層,確保每一個 Pilot 實例中 ZK 相同路徑的監聽最多隻用1個 watcher,獲取到 watcher 通知後,Pilot 根據內部的快照緩存 + 索引向全部關注者分發,大大下降了冗餘。
- 關鍵點 2:治理能力層及會話管理層實現了相似於 I/O 多路複用能力,經過併發提高吞吐。
![](http://static.javashuo.com/static/loading.gif)
結果方面有效應對了網絡抖動或批量發版的瞬間風暴壓力,壓測單 Pilot 實例能夠承載 6 萬以上的連接,時延 TP99 線 < 2.3ms、數據零丟失。
3.4.4 措施三:集中式健康檢測
針對大規模集羣內指數級膨脹的節點間健康監測次數,對應的措施是摒棄了 P2P 檢測模式,咱們參考並優化了 Google 的 Traffic Drector 中心化管理的健康檢測模式。這種模式下檢測次數大大減小,一個週期內 10 萬節點集羣的檢測次數,從 100 億次降低到 10 萬次。
此外,當 Pilot 感知到 Proxy 異常時,會當即通知中心化健康檢測系統啓動檢測,而不是等待檢測週期窗口的到來,這能夠有效提高業務調用的成功率。
![](http://static.javashuo.com/static/loading.gif)
3.5 交易型場景困境下的解決方案
3.5.1 業務屬性分析
美團內部業務線較多,包括外賣、配送、酒店、旅遊、單車、團購等,其中絕大多數業務都帶有交易屬性,交易鏈路上一個流量異常就可能影響到訂單。業務系統對新技術領域的探索每每比較慎重,指望在新技術充分驗證後再啓動試點,因此除小語種及亟待與公司打通的單車業務外,推廣的難度是很是大的。此外,基礎架構部秉承「以客戶爲中心」的原則,研發、運維、測試人員均是咱們的「客戶」,因此技術升級會重點從業務價值入手,並不是簡單依靠從上至下的政策推進力。
因此,咱們對外的承諾是:通訊足夠快、系統足夠穩定、接入足夠平滑高效。
![](http://static.javashuo.com/static/loading.gif)
3.5.2 精細化運營體系建設
針對推廣的困境,咱們首先作了兩件事情:
- 尋找具有強訴求的業務試點,客觀來講,美團技術棧內這類業務數量很是有限。
- 尋求標杆核心業務試點,充分驗證後推廣給其餘業務,但效果並不理想,與業務穩定性的訴求並不匹配。
針對上述困境,咱們進行深度思考後創建了一個精細化的運營體系:
- 服務接入 Mesh 前。基於 SOA 分級將服務劃分爲非核心與核心兩類,先針對非核心服務以及全部服務的線下環境進行重點突破,實現了在普遍的業務場景下,全面且充分的驗證系統能力。
- 服務接入 Mesh 中。運營系統經過校驗 SDK 版本、運行時環境等信息,自動篩選出知足條件的服務,業務同窗只須要在平臺上作(1)開啓開關、(2)選擇節點(3)指定 Mesh 流量比例三個步驟,就完成了到 Mesh 模式的切換,不需代碼改造也不需發佈服務,整個過程基本在 1 分鐘左右完成;此外,經過與 IM 工具深度聯動,提高了推廣與數據運營的效率。
- 服務接入 Mesh 後。一方面,業務側包括架構側的運營有詳細的數據指標作對比參考;另外一方面,運營系統支持預先設置穩定性策略並作準實時的檢測,當某個接入服務 Mesh 模式異常時,即時自動切換回非 Mesh 模式。
運營體系具有 「接入過程無感」、「精細化流量粒度灰度」、「異常自動回滾恢復」 三個核心能力,在運營體系建設後推廣運營較爲順利,目前線上接入的 600+ 服務、線下接入的 3500+ 服務中,90% 以上是依託運營平臺接入 Mesh 的。
3.5.3 通訊性能優化
在性能損耗優化這個方向,除使用 UDS 規避網絡棧外,咱們也經過增量聚合下發、序列化優化兩個措施減小沒必要要的解包,提高了通訊性能。
通過壓測,去除非核心功能在 2 核 4G 環境用 1KB 數據作 echo 測試,QPS 在 34000 以上,一跳平均延遲 0.207ms,時延TP99 線 0.4ms 左右。
3.5.4 流量多級保護
美團落地 Service Mesh 在穩定性保障方面建設投入較多,目前尚無 Service Mesh 引起的故障,具體包含三個方面:
首先作了流量多級保護
- 一方面,當 Proxy 不可用時,流量會自動 fallback 到非 Mesh 模式;另外一方面,支持最精細支持按單節點的 1/1000 比例灰度。下圖是具體的交互流程,固然,這兩個特性與 Service Mesh 的最終形態是衝突的,只是做爲系統建設初期優先保證業務穩定性的過渡性方案,長期來看必然是要去除的(包括美團一些核心服務已經徹底去除)。
- 基於 FD 遷移 + SDK 配合協議交互,實現 Proxy 無損熱重啓的能力。
- 控制面下發錯誤配置比停發配置的後果更爲嚴重,咱們建設了應用層面及系統層面的週期巡檢,從端到端的應用視角驗證正確性,避免或減小因變動引起的異常。
- 系統交互方面,經過限流、熔斷對中心化控制面作服務保護;系統內柔性可用,當控制面所有異常時,緩存機制也能協助 Proxy 在必定時間內可用。
4、總結
本文系統性的介紹美團在 Service Mesh 落地進程中面臨的「兼容性」、「異構性」、「規模化」、「交易屬性業務容錯性低」這四類複雜性挑戰,針對上述挑戰,咱們也詳細介紹了大規模私有云集羣場景下的優化思考及實踐方案。
基於上述實踐,目前美團線上落地服務數超過 600,線下服務數超過 3500+,初步驗證了模式的可行性。短時間價值方面,咱們支持了摩拜等異構治理體系的快速融合、多語言治理能力的統一;長期價值仍需在實踐中繼續探索與驗證,但在標準化服務治理運行時並與業務解耦、中心化管控下更豐富的治理能力輸出兩個方面,是很是值得期待的。
做者簡介
繼東、薛晨、業祥、張昀,均來自美團基礎技術部-基礎架構部。
招聘信息
基礎技術部-基礎架構部-中間件研發中心-服務框架組涉及領域主要包括 RPC 通訊框架、Service Mesh、服務治理門戶、Set化、流程引擎系統 Gravity等。感興趣的同窗可投遞簡歷至:tech@meituan.com(郵件主題請註明:基礎架構部)。
| 想閱讀更多技術文章,請關注美團技術團隊(meituantech)官方微信公衆號。在公衆號菜單欄回覆【2019年貨】、【2018年貨】、【2017年貨】、【算法】等關鍵詞,可查看美團技術團隊歷年技術文章合集。
![](http://static.javashuo.com/static/loading.gif)