螞蟻金服 Service Mesh 深度實踐

支付寶技術團隊發表於2019-11-08

作者丨敖小劍

2019 年,螞蟻金服在 Service Mesh 領域繼續高歌猛進,進入大規模落地的深水區。本文介紹了 Service Mesh 在螞蟻金服的落地情況和即將來臨的雙十一大考,以及大規模落地時遇到的困難和解決方案,助你瞭解 Service Mesh 的未來發展方向和前景。

一、前言

大家好,我是敖小劍,來自螞蟻金服中介軟體團隊,今天帶來的主題是“詩和遠方:螞蟻金服 Service Mesh 深度實踐”。

在過去兩年,我先後做過兩次 Service Mesh 的演講:

  • 2017 年,當時 Service Mesh 在國內還屬於蠻荒時代,我當時做了一個名為“Service Mesh: 下一代微服務”的演講,開始在國內佈道 Service Mesh 技術;
  • 2018 年,做了名為“長路漫漫踏歌而行:螞蟻金服 Service Mesh 實踐探索”的演講,介紹螞蟻金服在 Service Mesh 領域的探索性的實踐,當時螞蟻金服剛開始在 Service Mesh 探索。
  • 今天,有幸第三次,給大家帶來的依然是螞蟻金服在 Service Mesh 領域的實踐分享。和去年不同的是,今年螞蟻金服進入了 Service Mesh 落地的深水區,規模巨大,而且即將迎來雙十一大促考驗。

備註:現場做了一個調研,瞭解聽眾對 Servicve Mesh 的瞭解程度,結果不太理想:在此之前對 Service Mesh 有了解的同學目測只有 10% 多點(肯定不到 20%)。Service Mesh 的技術佈道,依然任重道遠。

今天給大家帶來的內容主要有三塊:

  1. 螞蟻金服落地情況介紹:包括大家最關心的雙十一落地情況;
  2. 大規模落地的困難和挑戰:分享一下我們過去一年中在大規模落地上遇到的問題;
  3. 是否採用 Service Mesh 的建議:這個問題經常被人問起,所以借這個機會給出一些中肯的建議供大家參考。

二、螞蟻金服落地情況介紹

(一)發展歷程和落地規模

螞蟻金服 Service Mesh 深度實踐

Service Mesh 技術在螞蟻金服的落地,先後經歷過如下幾個階段:

  • 技術預研 階段:2017 年底開始調研並探索 Service Mesh 技術,並確定為未來發展方向;
  • 技術探索 階段:2018 年初開始用 Golang 開發 Sidecar SOFAMosn,年中開源基於 Istio 的 SOFAMesh;
  • 小規模落地 階段:2018 年開始內部落地,第一批場景是替代 Java 語言之外的其他語言的客戶端 SDK,之後開始內部小範圍試點;
  • 規模落地 階段:2019 年上半年,作為螞蟻金融級雲原生架構升級的主要內容之一,逐漸鋪開到螞蟻金服內部的業務應用,並平穩支撐了 618 大促;
  • 全面大規模落地 階段:2019 年下半年,在螞蟻金服內部的業務中全面鋪開,落地規模非常龐大,而且準備迎接雙十一大促。

目前 ServiceMesh 正在螞蟻金服內部大面積鋪開,我這裡給出的資料是前段時間(大概 9 月中)在雲棲大會上公佈的資料:應用數百個,容器數量(pod 數)超過 10 萬。當然目前落地的 pod 數量已經遠超過 10 萬,這已經是目前全球最大的 Service Mesh 叢集,但這僅僅是一個開始,這個叢集的規模後續會繼續擴大,明年螞蟻金服會有更多的應用遷移到 Service Mesh。

(二)主要落地場景

螞蟻金服 Service Mesh 深度實踐

目前 Service Mesh 在螞蟻金服內部大量落地,包括支付寶的部分核心鏈路,落地的主要場景有:

  • 多語言支援:目前除了支援 Java 之外,還支援 Golang,Python,C++,NodeJS 等語言的相互通訊和服務治理;
  • 應用無感知的升級:關於這一點我們後面會有特別的說明;
  • 流量控制:經典的 Istio 精準細粒度流量控制;
  • RPC 協議支援:和 Istio 不同,我們內部使用的主要是 RPC 協議;
  • 可觀測性。

(三)Service Mesh 的實際效能資料

之前和一些朋友、客戶交流過,目前在 Service Mesh 方面大家最關心的是 Service Mesh 的效能表現,包括對於這次螞蟻金服 Service Mesh 上雙十一,大家最想看到的也是效能指標。

螞蟻金服 Service Mesh 深度實踐

為什麼大家對效能這麼關注?

因為在 Service Mesh 工作原理的各種介紹中,都會提到 Service Mesh 是將原來的一次遠端呼叫,改為走 Sidecar(而且像 Istio 是客戶端和伺服器端兩次 Sidecar,如上圖所示),這樣一次遠端呼叫就會變成三次遠端呼叫,對效能的擔憂也就自然而然的產生了:一次遠端呼叫變三次遠端呼叫,效能會下降多少?延遲會增加多少?

下圖是我們內部的大促壓測資料,對比帶 SOFAMosn 和不帶 SOFAMosn 的情況(實現相同的功能)。其中 SOFAMosn 是我們螞蟻金服自行開發的基於 Golang 的 Sidecar/ 資料平面,我們用它替代了 Envoy,在去年的演講中我有做過詳細的介紹。

SOFAMosn:

螞蟻金服 Service Mesh 深度實踐

  • CPU:CPU 使用在峰值情況下增加 8%,均值約增加 2%。在最新的一次壓測中,CPU 已經最佳化到基本持平(低於 1%);
  • 記憶體:帶 SOFAMosn 的節點比不帶 SOFAMosn 的節點記憶體佔用平均多 15M;
  • 延遲:延遲增加平均約 0.2ms。部分場景帶 SOFAMosn 比不帶 SOFAMosn RT 增加約 5%,但是有部分特殊場景帶 SOFAMosn 比不帶 SOFAMosn RT 反而降低 7.5%;

這個效能表現,和前面"一次遠端呼叫變三次遠端呼叫"的背景和擔憂相比有很大的反差。尤其是上面延遲的這個特殊場景,居然出現帶 SOFAMosn(三次遠端呼叫)比不帶 SOFAMosn(一次遠端呼叫) 延遲反而降低的情況。

是不是感覺不科學?

(四)Service Mesh 的基本思路

我們來快速回顧一下 Service Mesh 實現的基本思路:

螞蟻金服 Service Mesh 深度實踐

在基於 SDK 的方案中,應用既有業務邏輯,也有各種非業務功能。雖然透過 SDK 實現了程式碼重用,但是在部署時,這些功能還是混合在一個程式內的。

在 Service Mesh 中,我們將 SDK 客戶端的功能從應用中剝離出來,拆解為獨立程式,以 Sidecar 的模式部署,讓業務程式專注於業務邏輯:

業務程式:專注業務實現,無需感知 Mesh;

Sidecar 程式:專注服務間通訊和相關能力,與業務邏輯無關;

我們稱之為"關注點分離":業務開發團隊可以專注於業務邏輯,而底層的中介軟體團隊(或者基礎設施團隊)可以專注於業務邏輯之外的各種通用功能。

透過 Sidecar 拆分為兩個獨立程式之後,業務應用和 Sidecar 就可以實現“獨立維護”:我們可以單獨更新 / 升級業務應用或者 Sidecar。

(五)效能資料背後的情景分析

我們回到前面的螞蟻金服 Service Mesh 落地後的效能對比資料:從原理上說,Sidecar 拆分之後,原來 SDK 中的各種功能只是拆分到 Sidecar 中。整體上並沒有增減,因此理論上說 SDK 和 Sidecar 效能表現是一致的。由於增加了應用和 Sidecar 之間的遠端呼叫,效能不可避免的肯定要受到影響。

首先我們來解釋第一個問題:為什麼效能損失那麼小,和"一次遠端呼叫變三次遠端呼叫"的直覺不符?

螞蟻金服 Service Mesh 深度實踐

所謂的“直覺”,是將關注點都集中到了遠端呼叫開銷上,下意識的忽略了其他開銷,比如 SDK 的開銷、業務邏輯處理的開銷,因此:

螞蟻金服 Service Mesh 深度實踐

推匯出來的結果就是有 3 倍的開銷,效能自然會有非常大的影響。

但是,真實世界中的應用不是這樣:

  1. 業務邏輯的佔比很高:Sidecar 轉發的資源消耗相比之下要低很多,通常是十倍百倍甚至千倍的差異;
  2. SDK 也是有消耗的:即使不考慮各種複雜的功能特性,僅僅就報文(尤其是 Body)序列化的編解碼開銷也是不低的。而且,客戶端和伺服器端原有的編解碼過程是需要處理 Body 的,而在 Sidecar 中,通常都只是讀取 Header 而透傳 Body,因此在編解碼上要快很多。另外應用和 Sidecar 的兩次遠端通訊,都是走的 Localhost 而不是真實的網路,速度也要快非常多;

因此,在真實世界中,我們假定業務邏輯百倍於 Sidecar 的開銷,而 SDK 十倍於 Sidecar 的開銷,則:

螞蟻金服 Service Mesh 深度實踐

推匯出來的結果,效能開銷從 111 增加到 113,大約增加 2%。這也就解釋了為什麼我們實際給出的 Service Mesh 的 CPU 和延遲的效能損失都不大的原因。當然,這裡我是刻意選擇了 100 和 10 這兩個係數來拼湊出 2% 這個估算結果,以迎合我們前面給出“均值約增加 2%”的資料。這不是準確數值,只是用來模擬。

(六)情理當中的意外驚喜

前面的分析可以解釋效能開銷增加不多的情景,但是,還記得我們的資料中有一個不科學的地方嗎:“部分特殊場景帶 SOFAMosn 比不帶 SOFAMosn RT 反而降低 7.5%”。

理論上,無論業務邏輯和 SDK 的開銷比 Sidecar 的開銷大多少,也就是不管我們怎麼最佳化 Sidecar 的效能,其結果也只能接近零。無論如何不可能出現多兩個 Sidecar,CPU 消耗和延遲反而降低的情況。

這個“不科學”是怎麼出現的?

我們繼續來回顧這個 Service Mesh 的實現原理圖:

螞蟻金服 Service Mesh 深度實踐

出現效能大幅提升的主要的原因,是我們在 SOFAMosn 上做了大量的最佳化,特別是路由的快取。在螞蟻金服內部,服務路由的計算和處理是一個異常複雜的邏輯,非常耗資源。而在最近的最佳化中,我們為服務路由增加了快取,從而使得服務路由的效能得到了大幅提升。因此:

螞蟻金服 Service Mesh 深度實踐

備註:這裡我依然是刻意拼湊出 -7% 這個估算結果,請注意這不是準確數值,只是用來模擬示意。

也許有同學會說,這個結果不“公平”:這是最佳化了的服務路由實現在 PK 沒有最佳化的服務路由實現。的確,理論上說,在 Sidecar 中做的任何效能最佳化,在 SDK 裡面同樣可以實現。但是,在 SDK 上做的最佳化需要等整個呼叫鏈路上的應用全部升級到最佳化後的 SDK 之後才能完全顯現。而在傳統 SDK 方案中,SDK 的升級是需要應用配合,這通常是一個漫長的等待過程。很可能程式碼最佳化和發版一週搞定,但是讓全站所有應用都升級到新版本的 SDK 要花費數月甚至一年。

此時 Service Mesh 的優點就凸顯出來了:Service Mesh 下,業務應用和 Sidecar 可以“獨立維護” ,我們可以很方便的在業務應用無感知的情況下升級 Sidecar。因此,任何 Sidecar 的最佳化結果,都可以非常快速的獲取收益,從而推動我們對 Sidecar 進行持續不斷的升級。

前面這個延遲降低 7% 的例子,就是一個非常經典的故事:在中秋節前後,我們開發團隊的同學,不辭辛苦加班加點的進行壓測和效能調優,在一週之內連續做了多次效能最佳化,連發了多個效能最佳化的小版本,以“小步快跑”的方式,最後拿到了這個令大家都非常開心的結果。

總結: 持續不斷的最佳化 + 無感知升級 = 快速獲得收益。

這是一個意外驚喜,但又在情理之中:這是 SDK 下沉到基礎設施並具備獨立升級能力後帶來的紅利。

也希望這個例子,能夠讓大家更深刻的理解 Service Mesh 的基本原理和優勢。

三、大規模落地的困難和挑戰

當 Service Mesh 遇到螞蟻金服的規模,困難和挑戰也隨之而來:當規模達到一定程度時,很多原本很小的問題都會急劇放大。後面我將在效能、容量、穩定性、可維護性和應用遷移幾個方面給大家介紹我們遇到的挑戰和實踐。

螞蟻金服 Service Mesh 深度實踐

(一)資料平面的最佳化

在資料平面上,螞蟻金服採用了自行研發的基於 Golang 的方案:SOFAMosn。關於為什麼選擇全新開發 SOFAMosn,而不是直接使用 Envoy 的原因,在去年 QCon 的演講中我有過詳細的介紹,有興趣可以瞭解。

前面我們給出的效能資料,實際上主要是資料平面的效能,也就是作為 Sidecar 部署的 SOFAMosn 的效能表現。從資料上看 SOFAMosn 目前的效能表現還是很不錯的,這背後是我們在 SOFAMosn 上做了非常多的效能最佳化。

CPU 最佳化:在 SOFAMosn 中我們進行了 Golang 的 writev 最佳化,將多個包拼裝一次寫以降低 syscall 呼叫。測試中發現,Golang 1.9 的時候 writev 有記憶體洩露的 bug。當時 debug 的過程非常的辛苦...... 詳情見我們當時給 Golang 提交的 PR:

記憶體最佳化:在記憶體複用,我們發現報文直接解析會產生大量臨時物件。SOFAMosn 透過直接複用報文位元組的方式,將必要的資訊直接透過 unsafe.Pointer 指向報文的指定位置來避免臨時物件的產生;

延遲最佳化:前面我們談到 Sidecar 是透過只解析 Header 而透傳 Body 來保證效能的。針對這一點,我們進行了協議升級,以便快速讀取 Header。比如我們使用的 TR 協議請求頭和 Body 均為 hessian 序列化,效能損耗較大。而 Bolt 協議中 Header 是一個扁平化 map,解析效能損耗小。因此我們升級應用改走 Bolt 協議來提升 Sidecar 轉發的效能。這是一個典型的針對 Sidecar 特性而做的最佳化;

此外還有前面特意重點介紹的路由快取最佳化(也就是那個不科學的延遲降低 7% 的場景)。由於螞蟻金服內部路由的複雜性(一筆請求經常需要走多種路由策略最終確定路由結果目標),透過對相同條件的路由結果做秒級快取,我們成功將某核心鏈路的全鏈路 RT 降低 7%。

這裡我簡單給出了上述幾個典型案例,雙十一之後會有更多更詳細的 SOFAMosn 資料分享出來,有興趣的同學可以多關注。

在雙十一過後,我們也將加大 SOFAMosn 在開源上的投入,將 SOFAMosn 做更好地模組化地抽象,並且將雙十一中經過考驗的各種最佳化放進去,預計在 2020 年的 1 月底可以釋出第一個最佳化後的版本。

(二)Mixer 的效能最佳化

vMixer 的效能最佳化是個老生常談的話題,基本上只要談及 Istio 的效能,都避無可避。

Mixer 的效能問題,一直都是 Istio 中最被人詬病的地方。

尤其在 Istio 1.1/1.2 版本之後,引入 Out-Of-Process Adapter 之後,更是雪上加霜。

螞蟻金服 Service Mesh 深度實踐

原來 Sidecar 和 Mixer 之間的遠端呼叫已經嚴重影響效能,在引入 Out-Of-Process Adapter 之後又在 Traffic 流程中引入了新的遠端呼叫,效能更加不可接受。

從落地的角度看,Mixer V1 糟糕至極的效能,已經是“生命無法承受之重”。對於一般規模的生產級落地而言,Mixer 效能已經是難於接受,更不要提大規模落地……

Mixer V2 方案則給了社群希望:將 Mixer 合併進 Sidecar,引入 web assembly 進行 Adapter 擴充套件,這是我們期待的 Mixer 落地的正確姿勢,是 Mixer 的未來,是 Mixer 的"詩和遠方"。然而社群望穿秋水,但 Mixer V2 遲遲未能啟動,長期處於 In Review 狀態,遠水解不了近渴。

因此在 Mixer 落地上,我們只能接受妥協方案,所謂"眼前的苟且":一方面我們棄用 Mixer v1,改為在 SOFAMosn 中直接實現功能;另一方面我們並沒有實現 Mixer V2 的規劃。實際的落地方式是:我們只在 SOFAMosn 中提供最基本的策略檢查功能如限流,鑑權等,另外可觀測性相關的各種能力也都是從 SOFAMosn 直接輸出。

(三)Pilot 的效能最佳化

在 Istio 中,Pilot 是一個被 Mixer 掩蓋的重災區:長期以來大家的效能關注點都在 Mixer,表現糟糕而且問題明顯的 Mixer 一直在吸引火力。但是當選擇放棄 Mixer(典型如官方在 Istio 新版本中提供的關閉 Mixer 的配置開關)之後,Pilot 的效能問題也就很快浮出水面。

這裡簡單展示一下我們在 Pilot 上做的部分效能最佳化:

  • 序列化最佳化:我們全面使用 types.Any 型別,棄用 types.Struct 型別,序列化效能提升 70 倍,整體效能提升 4 倍。Istio 最新的版本中也已經將預設模式修改為 types.Any 型別。我們還進行了 CR(CustomResource) 的序列化快取,將序列化時機從 Get/List 操作提前至事件觸發時,並快取結果。大幅降低序列化頻率,壓測場景下整體效能提升 3 倍,GC 頻率大幅下降;
  • 預計算最佳化:支援 Sidecar CRD 維度的 CDS /LDS/RDS 預計算,大幅降低重複計算,壓測場景下整體效能提升 6 倍;支援 Gateway 維度的 CDS / LDS / RDS 預計算;計算變更事件的影響範圍,支援區域性推送,減少多餘的計算和對無關 Sidecar 的打擾;
  • 推送最佳化:支援執行時動態降級,支援熔斷閾值調整,限流閾值調整,靜默週期調整,日誌級別調整;實現增量 ADS 介面,在配置相關處理上,Sidecar cpu 減少 90%,Pilot cpu 減少 42%;

這裡簡單解釋一下,Pilot 在推送資料給 Sidecar 時,程式碼實現上的有些簡單:Sidecar 連線上 Pilot 時;Pilot 就給 Sidecar 下發 xDS 資料。假定某個服務有 100 個例項,則這 100 個例項的 Sidecar 連線到 Pilot 時,每次都會進行一次下發資料的計算,然後進行序列化,再下發給連上來的 Sidecar。下一個 Sidecar 連線上來時,重複這些計算和序列化工作,而不管下發的資料是否完全相同,我們稱之為“千人千面”。

而實際中,同一個服務往往有多個例項,Pilot 下發給這些例項的 Sidecar 的資料往往是相同的。因此我們做了最佳化,提前做預計算和序列化並快取結果,以便後續重複的例項可以直接從快取中取。因此,“千人千面”就可以最佳化為“千人百面”或者“千人十面”,從而大幅提高效能。

另外,對於整個 Service Mesh 體系,Pilot 至關重要。因此 Pilot 本身也應該進行保護,也需要諸如熔斷 / 限流等特性。

(四)Service Mesh 的運維

在 Service Mesh 的運維上,我們繼續堅持“線上變更三板斧”原則。這裡的變更,包括髮布新版本,也包括修改配置,尤其特指修改 Istio 的 CRD。

螞蟻金服 Service Mesh 深度實踐

線上變更“三板斧”指的是:

  • 可灰度:任何變更,都必須是可以灰度的,即控制變更的生效範圍。先做小範圍內變更,驗證透過之後才擴大範圍;
  • 可監控:在灰度過程中,必須能做到可監控,能瞭解到變更之後對系統的應用。如果沒有可監控,則可灰度也就沒有意義了;
  • 可回滾:當透過監控發現變更後會引發問題時,還需要有方法可以回滾;
  • 我們在這裡額外引入了一個名為“ScopeConfig”的配置變更生效範圍的控制能力,即配置變更的灰度。什麼是配置變更的灰度呢?

Istio 的官方實現,預設修改配置(Istio API 對應的各種 CRD)時新修改的配置會直接全量推動到所有生效的 Sidecar,即配置變更本身無法灰度。注意這裡和平時說的灰度不同,比如最常見的場景,服務 A 呼叫服務 B,並假定服務 A 有 100 個例項,而服務 B 有 10 個 v1 版本的服務例項正在進行。此時需要更新服務 B 到新的 v2 版本。為了驗證 v2 新版本,我們通常會選擇先上線一個服務 B 的 v2 版本的新例項,透過 Istio 進行流量百分比拆分,比如切 1% 的流量到新的 v2 版本的,這被稱為“灰度釋出”。此時新的“切 1% 流量到 v2”的 CRD 被下發到服務 A 的 Sidecar,這 100 個 Sidecar 中的每個都會執行該灰度策略。如果 v2 版本有問題不能正常工作,則隻影響到 1% 的流量,即此時 Istio 的灰度控制的是 CRD 配置生效之後 Sidecar 的流量控制行為。

但是,實際生產中,配置本身也是有風險的。假設在配置 Istio CRD 時出現低階錯誤,不小心將新舊版本的流量比例配反了,錯誤配置成了 99% 的流量去 v2 版本。則當新的 CRD 配置被下發到全部 100 個服務 A 的例項時並生效時, Sidecar 控制的流量就會發生非常大的變化,造成生產事故。

為了規避這個風險,就必須引入配置變更的範圍控制,比如將新的 CRD 配置下發到少數 Sidecar,驗證配置無誤後再擴充套件到其他 Sidecar。

(五)應用平滑遷移的終極方案

在 Service Mesh 落地的過程中,現有應用如何平滑遷移到 Service Mesh,是一個至關重要的話題。典型如基於傳統微服務框架如 SpringCloud/Dubbo 的應用,如何逐個(或者分批)的遷移到 Service Mesh 上。

螞蟻金服在去年進行落地實踐時,就特別針對應用平滑遷移進行了深入研究和探索。這個問題是 Service Mesh 社群非常關注的核心落地問題,今天我們重點分享。

在今年 9 月份的雲棲大會上,螞蟻金服推出了雙模微服務的概念,如下圖所示:

螞蟻金服 Service Mesh 深度實踐

“雙模微服務”是指傳統微服務和 Service Mesh 雙劍合璧,即“基於 SDK 的傳統微服務”可以和“基於 Sidecar 的 Service Mesh 微服務”實現下列目標:

  • 互聯互通:兩個體系中的應用可以相互訪問;
  • 平滑遷移:應用可以在兩個體系中遷移,對於呼叫該應用的其他應用,做到透明無感知;
  • 靈活演進:在互聯互通和平滑遷移實現之後,我們就可以根據實際情況進行靈活的應用改造和架構演進。

雙模還包括對應用執行平臺的要求,即兩個體系下的應用,既可以執行在虛擬機器之上,也可以執行在容器 /k8s 之上。

怎麼實現這麼一個美好的雙模微服務目標呢?

我們先來分析一下傳統微服務體系和 Service Mesh 體系在服務註冊 / 服務發現 / 服務相關的配置下發上的不同。

首先看傳統微服務體系,其核心是服務註冊中心 / 配置中心,應用透過引用 SDK 的方式來實現對接各種註冊中心 / 配置中心。通常不同的註冊中心 / 配置中心都有各自的實現機制和介面協議,SDK 和註冊中心 / 配置中心的互動方式屬於內部實現機制,並不通用。

螞蟻金服 Service Mesh 深度實踐

優點是支援海量資料(十萬級別甚至百萬級別),具備極強的分發能力,而且經過十餘年間的打磨,穩定可靠可謂久經考驗。市面上有很多成熟的開源產品,各大公司也都有自己的穩定實現。如阿里集團的 Nacos,螞蟻金服的 SOFARegistry。

SOFARegistry:

缺點是註冊中心 / 配置中心與 SDK 通常是透傳資料,即註冊中心 / 配置中心只進行資料的儲存和分發。大量的控制邏輯需要在 SDK 中實現,而 SDK 是嵌入到應用中的。因此,任何變更都需要改動 SDK 並要求應用升級。

再來看看 Service Mesh 方案,以 Istio 為例:

螞蟻金服 Service Mesh 深度實踐

Service Mesh 的優點是引入了控制平面(在 Istio 中具體指 Pilot 元件),透過控制平面來提供強大的控制邏輯。而控制平面的引入,MCP/xDS 等標準協議的制訂,實現了資料來源和下發資料的解耦。即儲存於註冊中心 / 配置中心(在 Istio 中體現為 k8s api server + Galley)的資料可以有多種靈活的表現形式,如 CRD 形式的 Istio API,透過執行於 Pilot 中的 Controller 來實現控制邏輯和格式轉換,最後統一轉換到 xDS/UDPA。這給 API 的設計提供了非常大的施展空間,極具靈活度,擴充套件性非常好。

缺點也很明顯,和成熟的註冊中心 / 配置中心相比,支援的容量有限,下發的效能和穩定性相比之下有很大差距。

控制平面和傳統註冊中心 / 配置中心可謂各有千秋,尤其他們的優缺點是互補的,如何結合他們的優勢?

此外,如何打通兩個體系是 Service Mesh 社群的老大難問題。尤其是缺乏標準化的社群方案,只能自行其是,各自為戰。

最近,在綜合了過去一年多的思考和探索之後,螞蟻金服和阿里集團的同事們共同提出了一套完整的解決方案,我們戲稱為“終極方案”:希望可以透過這個方案打通傳統微服務體系和 Service Mesh 體系,徹底終結這個困擾已久的問題。

這個方案的核心在於: 以 MCP 和 xDS/UDPA 協議為基礎,融合控制平面和傳統註冊中心 / 配置中心。

螞蟻金服 Service Mesh 深度實踐

如上圖所示,如果我們將融合控制平面和傳統註冊中心 / 配置中心而來的新的產品形態視為一個整體,則這個新產品形態的能力主要有三塊:

  1. 傳統註冊中心的資料儲存能力:支援海量資料;
  2. Service Mesh 控制平面的能力:解耦之後 API 設計的彈性和靈活度;
  3. 傳統註冊中心的分發能力:效能、速度、穩定性。

這個新的產品形態可以理解為“帶控制平面的註冊中心 / 配置中心”,或者“儲存 / 分發能力加強版的控制平面”。名字不重要,重要的是各節點的 通訊互動協議必須標準化:

  • MCP 協議:MCP 協議是 Istio 中用 於 Pilot 和 Galley 之間同步資料的協議,源自 xDS 協議。我們設想透過 MCP 協議將不同源的註冊中心整合起來,目標是聚合多註冊中心的資料到 Pilot 中,實現打通異構註冊中心(未來也會用於多區域聚合)。
  • xDS/UDPA 協議:xDS 協議源自 Envoy,是目前資料平面的事實標準,UDPA 是正在進行中的基於 xDS 協議的標準化版本。Sidecar 基於 xDS/UDPA 協議接入控制平面,我們還有進一步的設想,希望加強 SDK 方案,向 Istio 的功能靠攏,具體表現為 SDK 支援 xDS 協議(初期版本先實現最小功能集)。目標是希望在對接控制平面的前提下,應用可以在 Service Mesh 和 SDK 方案之間自由選擇和遷移。

基於這個思路,我們給出如下圖所示的解決方案,希望最大限度的整合傳統微服務框架和 Service Mesh。其基本指導原則是: 求同存異,保持相容。

螞蟻金服 Service Mesh 深度實踐

上圖中,藍色部分是通用的功能模組,我們希望可以和社群一起共建。紅色部分是不相容的功能模組,但是保持 API 相容。

具體說,右邊是各種註冊中心(配置中心同理):

  • Galley 和底下的 k8s API Server 可以視為一個特殊的註冊中心,這是 Istio 的官方方式;
  • Nacos/SOFARegistry 是阿里集團和螞蟻金服的註冊中心,支援海量規模。我們計劃新增 MCP 協議的支援,直接對接 Pilot;
  • 其他的註冊中心,也可以透過提供 MCP 協議支援的方式,接入到這個方案中;
  • 對於不支援 MCP 的註冊中心,可以透過開發一個 MCP Proxy 模組以介面卡模式的方式間接接入。當然最理想的狀態是出現成熟的通用開源方案來統一解決,比如 Nacos Sync 有計劃做類似的事情;


左邊是資料平面:

  • Service Mesh 體系下的 Sidecar(如 Envoy 和螞蟻金服的 SOFAMosn)目前都已經支援 xDS/UDPA;
  • 相對來說,這個方案中比較“腦洞”的是在 SDK 方案如 Spring Cloud/Dubbo/SOFARPC 中提供 xDS 的支援,以便對接到已經彙總了全域性資料的控制平面。從這個角度說,支援 xDS 的 SDK 方案,也可以視為廣義的資料平面。我們希望後面可以推動社群朝這個方向推進,短期可以先簡單對接,實現 xDS 的最小功能集;長期希望 SDK 方案的功能能向 Istio 看齊,實現更多的 xDS 定義的特性;
  • 這個方案對執行平臺沒有任何特別要求,只要網路能通,應用和各個元件可以靈活選擇執行在容器(k8s)中或虛擬機器中。

需要特別強調的是,這個方案最大的優點在於它是一個高度標準化的社群方案:透過 MCP 協議和 xDS 協議對具體實現進行了解耦和抽象,整個方案沒有繫結到任何產品和供應商。因此,我們希望這個方案不僅僅可以用於阿里集團和螞蟻金服,也可以用於整個 Istio 社群。阿里集團和螞蟻金服目前正在和 Istio 社群聯絡,我們計劃將這個方案貢獻出來,並努力完善和加強 Pilot 的能力,使之能夠滿足我們上面提到的的美好願景:融合控制平面和傳統註冊中心 / 配置中心的優點,打通傳統微服務框架和 Service Mesh,讓應用可以平滑遷移靈活演進。

希望社群認可這個方案的同學可以參與進來,和我們一起努力來建設和完善它。

四、是否採用 Service Mesh 的建議

在過去一年間,這個問題經常被人問起。借這個機會,結合過去一年中的實踐,以及相比去年此時更多的心得和領悟,希望可以給出一些更具參考價值的建議。

(一)建議一:有沒有直接痛點

有沒有短期急迫需求,通常取決於當前有沒有迫切需要解決的痛點。

在 Service Mesh 的發展過程中,有兩個特別清晰而直接的痛點,它們甚至對 Service Mesh 的誕生起了直接的推動作用:

1.多語言支援

這是 SDK 方案的天然侷限,也是 Service Mesh 的天然優勢。需要支援的程式語言越多,為每個程式語言開發和維護一套 SDK 的成本就越高,就有越多的理由採用 Service Mesh。

2.類庫升級困難

螞蟻金服 Service Mesh 深度實踐

同樣,這也是 SDK 方案的天然侷限,也是 Service Mesh 的天然優勢(還記得前面那個不科學的 -7% 嗎?)。SDK 方案中類庫和業務應用打包在一起,升級類庫就不得不更新整個業務應用,而且是需要更新所有業務團隊的所有應用。在大部分公司,這通常是一個非常困難的事情,而且每次 SDK 升級都要重複一次這種痛苦。

而且,這兩個痛點有可能會同時存在:有多個程式語言的類庫需要升級版本......

所以,第一個建議是先檢查是否存在這兩個痛點。

(二)建議二:老應用升級改造

Service Mesh 的無侵入性,在老應用升級改造,尤其是希望少改程式碼甚至完全不改程式碼的情況下,堪稱神器。

螞蟻金服 Service Mesh 深度實踐

所以,第二個建議是,如果有老應用無改動升級改造的需求,對流量控制、安全、可觀測性有訴求,則可以考慮採用 Service Mesh。

(三)建議三:維護統一的技術棧

這個建議僅僅適用於技術力量相對薄弱的企業,這些企業普遍存在一個問題:技術力量不足,或者主要精力投放在業務實現,導致無力維護統一的技術棧,系統呈現煙囪式架構。

螞蟻金服 Service Mesh 深度實踐

傳統煙囪式架構的常見問題有:

  • 重複建設,重複造輪子;
  • 不同時期,不同廠商,用不同的輪子;
  • 難以維護和演進,後續成本高昂;
  • 掌控力不足,容易受制於人;

這種情況下,建議引入 Service Mesh 技術,透過 Service Mesh 將非業務邏輯從應用剝離並下沉的特性,來統一整個公司的技術棧。

特別需要強調的是,對於技術力量不足、嚴重依賴外包和採購的企業,尤其是銀行 / 保險 / 證券類金融企業,引入 Service Mesh 會有一個額外的特殊功效,至關重要:

將乙方限制在業務邏輯的實現上

即企業自行建設和控制 Service Mesh,作為統一的技術棧,在其上再開發執行業務應用。由於這些業務應用執行在 Servcie Mesh 之上,因此只需要實現業務邏輯,非業務邏輯的功能由 Servcie Mesh 來提供。透過這種方式,可以避免乙方公司借專案機會引入各種技術棧而造成技術棧混亂,導致後期維護成本超高;尤其是要避免引入私有技術棧,因為私有技術棧會造成對甲方事實上的技術繫結(甚至技術綁架)。

(四)建議四:雲原生落地

最後一個建議,和雲原生有關。在去年的 QCon 演講中,我曾經提到我們在探索 Kubernetes / Service Mesh / Serverless 結合的思路。在過去一年,螞蟻金服一直在雲原生領域做深度探索,也有一些收穫。其中,有一點我們是非常明確的:Mesh 化是雲原生落地的關鍵步驟。

下圖展示了螞蟻金服在雲原生落地方面的基本思路:

螞蟻金服 Service Mesh 深度實踐

  • 最下方是雲,以 Kubernetes 為核心,關於這一點社群基本已經達成共識:Kubernetes 就是雲原生下的作業系統;
  • 在 Kubernetes 之上,是 Mesh 層。不僅僅有我們熟悉的 Service Mesh,還有諸如 Database Mesh 和 Message Mesh 等類似的其他 Mesh 產品形態,這些 Mesh 組成了一個標準化的通訊層;
  • 執行在各種 Mesh 的應用,不管是微服務形態,還是傳統非微服務形態,都可以藉助 Mesh 的幫助實現應用輕量化,非業務邏輯的各種功能被剝離到 Mesh 中後,應用得以“瘦身減負”;
  • 瘦身之後的應用,其內容主要是業務邏輯實現。這樣的工作負載形式,更適合 Serverless 的要求,為接下來轉型 Serverless 做好準備;

所以,我的最後一個建議是,請結合你的長遠發展方向考慮:如果雲原生是你的詩和遠方,那麼 Service Mesh 就是必由之路。

螞蟻金服 Service Mesh 深度實踐

Kubernetes / Service Mesh / Serverless 是當下雲原生落地實踐的三駕馬車,相輔相成,相得益彰。

(五)Service Mesh 的核心價值

在最後,重申一下 Service Mesh 的核心價值:

實現業務邏輯和非業務邏輯的分離。

前面的關於要不要採用 Service Mesh 四個建議,歸根到底,最終都是對這個核心價值的延展。只有在分離業務邏輯和非業務邏輯並以 Sidecar 形式獨立部署之後,才有了這四個建議所依賴的特性:

  • Service Mesh 的多語言支援和應用無感知升級;
  • 無侵入的為應用引入各種高階特性如流量控制,安全,可觀測性;
  • 形成統一的技術棧;
  • 為非業務邏輯相關的功能下沉到基礎設施提供可能,幫助應用輕量化,使之專注於業務,進而實現應用雲原生化。

希望大家在理解 Service Mesh 的核心價值之後,再來權衡要不要採用 Service Mesh,也希望我上面給出的四個建議可以對大家的決策有所幫助。

五、總結

在今天的內容中,首先介紹了螞蟻金服 Service Mesh 的發展歷程,給大家展示了雙十一大規模落地的規模和效能指標,並解釋了這些指標背後的原理。然後分享了螞蟻金服在 Service Mesh 大規模落地中遇到的困難和挑戰,以及我們為此做的工作,重點介紹了應用平滑遷移的所謂“終極方案”;最後結合螞蟻金服在雲原生和 Service Mesh 上的實踐心得,對於是否應該採用 Service Mesh 給出了幾點建議。

目前螞蟻金服正在靜待今年的雙十一大考,這將是 Service Mesh 的歷史時刻:全球最大規模的 Service Mesh 叢集,Service Mesh 首次超大規模部署...... 一切都是如此的值得期待。

請對 Service Mesh 感興趣的同學稍後繼續關注,預期在雙十一之後會有一系列的分享活動:

螞蟻金服 Service Mesh 深度實踐

  • 經驗分享:會有更多的技術分享,包括落地場景,經驗教訓,實施方案,架構設計…
  • 開源貢獻:螞蟻金服會將落地實踐中的技術實現和方案以不同的方式回饋社群,推動 Service Mesh 落地實踐。目前這個工作正在實質性的進行中, 請留意我們稍後公佈的訊息;
  • 商務合作:螞蟻金服即將推出 Service Mesh 產品,提供商業產品和技術支援,提供金融級特性,歡迎聯絡;
  • 社群交流:ServiceMesher 技術社群繼續承擔國內 Service Mesh 佈道和交流的重任;歡迎參加我們今年正在持續舉辦的 Service Mesh Meetup 活動。

螞蟻金服 Service Mesh 深度實踐

今年是我在 QCon 演講的第三年,這三年中的三次演講,可以說是從一個側面反映了國內 Service Mesh 發展的不同階段:

2017 年,國內 Service Mesh 一片蠻荒的時候,我做了 Service Mesh 的佈道,介紹了 Service Mesh 的原理,喊出了“下一代微服務”的口號。

2018 年,以螞蟻金服為代表的國內網際網路企業,陸陸續續開始了 Service Mesh 的落地探索,所謂摸著石頭過河不外如是。第二次演講我分享了螞蟻金服的探索性實踐,介紹了螞蟻金服的 Service Mesh 落地方式和思路。

今天,2019 年,第三次演講,螞蟻金服已經建立起了全球最大規模的 Service Mesh 叢集並準備迎接雙十一的嚴峻挑戰,這次的標題也變成了深度實踐。

從佈道,到探索,再到深度實踐,一路走來已是三年,國內的 Service Mesh 發展,也從籍籍無名,到炙手可熱,再到理性迴歸。Service Mesh 的落地,依然還存在非常多的問題,距離普及還有非常遠的路要走,然而 Service Mesh 的方向,已經被越來越多的人瞭解和認可。

高曉松說:"生活不止眼前的苟且,還有詩和遠方"。對於 Service Mesh 這樣的新技術來說,也是如此。

2020 年,螞蟻金服將繼續推進和擴大 Service Mesh 落地的規模,繼續引領 Service Mesh 在金融行業的實踐探索。希望明年,可以有更多更深入的內容帶給大家!

六、作者介紹

敖小劍,螞蟻金服高階技術專家,十七年軟體開發經驗,微服務專家,Service Mesh 佈道師,ServiceMesher 社群聯合創始人。專注於基礎架構和中介軟體,Cloud Native 擁護者,敏捷實踐者,堅守開發一線打磨匠藝的架構師。曾在亞信、愛立信、唯品會等任職,目前就職螞蟻金服,在中介軟體團隊從事 Service Mesh/ Serverless 等雲原生產品開發。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69904796/viewspace-2663171/,如需轉載,請註明出處,否則將追究法律責任。

相關文章