天天看點

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

敖小劍,螞蟻金服進階技術專家,十七年軟體開發經驗,微服務專家,Service Mesh 布道師,ServiceMesher 社群聯合創始人。專注于基礎架構和中間件,Cloud Native 擁護者,靈活實踐者,堅守開發一線打磨匠藝的架構師。曾在亞信、愛立信、唯品會等任職,目前就職螞蟻金服,在中間件團隊從事 Service Mesh/ Serverless 等雲原生産品開發。本文整理自10月18日在 QCon 上海 2019 上的演講内容。

前言

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

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

今天,有幸第三次來到 QCon,給大家帶來的依然是螞蟻金服在 Service Mesh 領域的實踐分享。和去年不同的是,今年螞蟻金服進入了 Service Mesh 落地的深水區,規模巨大,而且即将迎來雙十一大促考驗。

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

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

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

螞蟻金服落地情況介紹

發展曆程和落地規模

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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 深度實踐 | QCon 實錄

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

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

Service Mesh 的實際性能資料

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

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

SOFAMosn:

https://github.com/sofastack/sofa-mosn
詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄
  • 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 深度實踐 | QCon 實錄

在基于 SDK 的方案中,應用既有業務邏輯,也有各種非業務功能。雖然通過 SDK 實作了代碼重用,但是在部署時,這些功能還是混合在一個程序内的。

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

  • 業務程序:專注業務實作,無需感覺 Mesh;
  • Sidecar 程序:專注服務間通訊和相關能力,與業務邏輯無關;

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

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

性能資料背後的情景分析

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

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

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

情理當中的意外驚喜

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

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

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

出現性能大幅提升的主要的原因,是我們在 SOFAMosn 上做了大量的優化,特别是路由的緩存。在螞蟻金服内部,服務路由的計算和處理是一個異常複雜的邏輯,非常耗資源。而在最近的優化中,我們為服務路由增加了緩存,進而使得服務路由的性能得到了大幅提升。是以:

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄
備注:這裡我依然是刻意拼湊出-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 深度實踐 | QCon 實錄

資料平面的優化

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

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

  • CPU 優化:在 SOFAMosn 中我們進行了 Golang 的 writev 優化,将多個包拼裝一次寫以降低 syscall 調用。測試中發現,Golang 1.9 的時候 writev 有記憶體洩露的 bug。當時 debug 的過程非常的辛苦...... 詳情見我們當時給 Golang 送出的 PR: https://github.com/golang/go/pull/32138
  • 記憶體優化:在記憶體複用,我們發現封包直接解析會産生大量臨時對象。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 的性能優化

Mixer 的性能優化是個老生常談的話題,基本上隻要談及 Istio 的性能,都避無可避。

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

原來 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 深度實踐 | QCon 實錄

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

  1. 可灰階:任何變更,都必須是可以灰階的,即控制變更的生效範圍。先做小範圍内變更,驗證通過之後才擴大範圍;
  2. 可監控:在灰階過程中,必須能做到可監控,能了解到變更之後對系統的應用。如果沒有可監控,則可灰階也就沒有意義了;
  3. 可復原:當通過監控發現變更後會引發問題時,還需要有方法可以復原;

我們在這裡額外引入了一個名為“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 深度實踐 | QCon 實錄

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

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

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

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

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

首先看傳統微服務體系,其核心是服務注冊中心/配置中心,應用通過引用 SDK 的方式來實作對接各種注冊中心/配置中心。通常不同的注冊中心/配置中心都有各自的實作機制和接口協定,SDK 和注冊中心/配置中心的互動方式屬于内部實作機制,并不通用。

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

SOFARegistry:

https://github.com/sofastack/sofa-registry

缺點是注冊中心/配置中心與 SDK 通常是透傳資料,即注冊中心/配置中心隻進行資料的存儲和分發。大量的控制邏輯需要在 SDK 中實作,而 SDK 是嵌入到應用中的。是以,任何變更都需要改動 SDK 并要求應用更新。

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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 深度實踐 | QCon 實錄

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

  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 深度實踐 | QCon 實錄

上圖中,藍色部分是通用的功能子產品,我們希望可以和社群一起共建。紅色部分是不相容的功能子產品,但是保持 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. 多語言支援
詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

  1. 類庫更新困難
詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

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

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

建議二:老應用更新改造

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

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

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

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

将乙方限制在業務邏輯的實作上

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

建議四:雲原生落地

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

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄
  • 最下方是雲,以 Kubernetes 為核心,關于這一點社群基本已經達成共識:Kubernetes 就是雲原生下的作業系統;
  • 在 Kubernetes 之上,是 Mesh 層。不僅僅有我們熟悉的 Service Mesh,還有諸如 Database Mesh 和 Message Mesh 等類似的其他 Mesh 産品形态,這些 Mesh 組成了一個标準化的通信層;
  • 運作在各種 Mesh 的應用,不管是微服務形态,還是傳統非微服務形态,都可以借助 Mesh 的幫助實作應用輕量化,非業務邏輯的各種功能被剝離到 Mesh 中後,應用得以“瘦身減負”;
  • 瘦身之後的應用,其内容主要是業務邏輯實作。這樣的工作負載形式,更适合 Serverless 的要求,為接下來轉型 Serverless 做好準備;

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

詩和遠方:螞蟻金服 Service Mesh 深度實踐 | QCon 實錄

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

今年是我在 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 這樣的新技術來說,也是如此。

鳴謝 InfoQ 和 Qcon 提供的機會,讓我得以每年一次的為大家分享 Service Mesh 的内容。2020年,螞蟻金服将繼續推進和擴大 Service Mesh 落地的規模,繼續引領 Service Mesh 在金融行業的實踐探索。希望明年,可以有更多更深入的内容帶給大家!