阿里巴巴 Service Mesh 落地的架構與挑戰

雲原生已成爲整個阿里巴巴經濟體構建面向未來的技術基礎設施,Service Mesh 作爲雲原生的關鍵技術之一,順利完成在 雙11 核心應用嚴苛而複雜場景下的落地驗證。本文作者將與大家分享在完成這一目標過程中我們所面臨和克服的挑戰。

部署架構

切入主題前,需要交代一下在 雙11 核心應用上落地的部署架構,如下圖所示。在這篇文章中,我們主要聚焦於 Service A 和 Service B 之間 RPC 協議的 Mesh 化。

圖中示例說明了 Service Mesh 所包含的三大平面:即數據平面(Data Plane)、控制平面(Control Plane)和運維平面(Operation Plane)。數據平面我們採用的是開源的 Envoy(上圖中的 Sidecar,請讀者注意這兩個詞在本文中可以互換使用),控制平面採用的是開源的 Istio(目前只使用了其中的 Pilot 組件),運維平面則完全自研。

與半年前落地時不同,這次 雙11 核心應用上落地我們採用了 Pilot 集羣化部署的模式,即 Pilot 不再與 Envoy 一起部署到業務容器中,而是搭建了一個獨立的集羣。這一變化使得控制平面的部署方式演進到了 Service Mesh 應有的終態。

挑戰

落地所選擇的 雙11 核心應用都是採用 Java 編程語言實現的,在落地的過程中我們面臨了以下挑戰。

1. 在 SDK 無法升級的情形下如何實現應用的 Mesh 化

在決定要在 雙11 的核心應用上落地 Mesh 時,Java 應用依賴的 RPC SDK 版本已經定稿,爲了 Mesh 化完全沒有時間去開發一個適用於 Mesh 的 RPC SDK 並做升級。那時,擺在團隊面前的技術問題是:如何在不升級 SDK 的情形下,實現 RPC 協議的 Mesh 化?

熟悉 Istio 的讀者想必清楚,Istio 是通過 iptables 的 NAT 表去做流量透明攔截的,通過流量透明攔截可在應用無感的情形下將流量劫持到 Envoy 中從而實現 Mesh 化。但很不幸,NAT 表所使用到的 nf_contrack 內核模塊因爲效率很低,在阿里巴巴的線上生產機器中被去除了,因此無法直接使用社區的方案。好在年初開始不久我們與阿里巴巴 OS 團隊達成了合作共建,由他們負責承擔 Service Mesh 所需的流量透明攔截和網絡加速這兩塊基礎能力的建設。經過兩個團隊的緊密合作,OS 團隊探索了通過基於 userid 和 mark 標識流量的透明攔截方案,基於 iptables 的 mangle 表實現了一個全新的透明攔截組件。

下圖示例說明了存在透明攔截組件的情形下,RPC 服務調用的流量走向。其中,Inbound 流量是指調進來的流量(流量的接受者是 Provider 角色),而 Outbound 是指調出去的流量(流量的發出者是 Consumer 角色)。通常一個應用會同時承擔兩個角色,所以有 Inbound 和 Outbound 兩股流量並存。

有了透明攔截組件之後,應用的 Mesh 化完全能做到無感,這將極大地改善 Mesh 落地的便利性。當然,由於 RPC 的 SDK 仍存在以前的服務發現和路由邏輯,而該流量被劫持到 Envoy 之後又會再做一次,這將導致 Outbound 的流量會因爲存在兩次服務發現和路由而增加 RT,這在後面的數據部分也將有所體現。顯然,以終態落地 Service Mesh 時,需要去除 RPC SDK 中的服務發現與路由邏輯,將相應的 CPU 和內存開銷給節約下來。

2.短時間內支持電商業務複雜的服務治理功能

路由

在阿里巴巴電商業務場景下的路由特性豐富多樣,除了要支持單元化、環境隔離等路由策略,還得根據 RPC 請求的方法名、調用參數、應用名等完成服務路由。阿里巴巴內部的 Java RPC 框架是通過嵌入 Groovy 腳本來支持這些路由策略的,業務方在運維控制檯上配置 Groovy 路由模板,SDK 發起調用時會執行該腳本完成路由策略的運用。

未來的 Service Mesh 並不打算提供 Groovy 腳本那麼靈活的路由策略定製方案,避免因爲過於靈活而給 Service Mesh 自身的演進帶去掣肘。因此,我們決定借 Mesh 化的機會去除 Groovy 腳本。通過落地應用所使用 Groovy 腳本的場景分析,我們抽象出了一套符合雲原生的解決方案:擴展 Istio 原生的 CRD 中的 VirtualService 和 DestinationRule,增加 RPC 協議所需的路由配置段去表達路由策略。

目前阿里巴巴環境下的單元化、環境隔離等策略都是在 Istio/Envoy 的標準路由模塊內做了定製開發,不可避免地存在一些 hack 邏輯。未來計劃在 Istio/Envoy 的標準路由策略之外,設計一套基於 Wasm 的路由插件方案,讓那些簡單的路由策略以插件的形式存在。如此一來,既減少了對標準路由模塊的侵入,也在一定程度上滿足了業務方對服務路由定製的需要。設想的架構如下圖所示:

限流

出於性能考慮,阿里巴巴內部落地的 Service Mesh 方案並沒有採用 Istio 中的 Mixer 組件,限流這塊功能借助阿里巴巴內部廣泛使用的 Sentinel 組件來實現,不僅可以與已經開源的 Sentinel 形成合力,還可以減少阿里巴巴內部用戶的遷移成本(直接兼容業務的現有配置來限流)。爲了方便 Mesh 集成,內部多個團隊合作開發了 Sentinel 的 C++版本,整個限流的功能是通過 Envoy 的 Filter 機制來實現的,我們在 Dubbo 協議之上構建了相應的 Filter(Envoy 中的術語,代表處理請求的一個獨立功能模塊),每個請求都會經過 Sentinel Filter 做處理。限流所需的配置信息則是通過 Pilot 從 Nacos 中獲取,並通過 xDS 協議下發到 Envoy 中。

3. Envoy 的資源開銷過大

Envoy 誕生之初要解決的一個核心問題就是服務的可觀測性,因此 Envoy 一開始就內置了大量的 stats(即統計信息),以便更好地對服務進行觀測。

Envoy 的 stats 粒度很細,甚至細到整個集羣的 IP 級別,在阿里巴巴環境下,某些電商應用的 Consumer 和 Provider 服務加起來達到了幾十萬之多的 IP(每個 IP 在不同的服務下攜帶的元信息不同,所以不同的服務下的相同 IP 是各自獨立的)。如此一來,Envoy 在這塊的內存開銷甚是巨大。爲此,我們給 Envoy 增加了 stats 開關,用於關閉或打開 IP 級別的 stats,關閉 IP 級別的 stats 直接帶來了內存節約 30% 成果。下一步我們將跟進社區的 stats symbol table 的方案來解決 stats 指標字符串重複的問題,那時的內存開銷將進一步減少。

4. 解耦業務與基礎設施,實現基礎設施升級對業務無感

Service Mesh 落地的一項核心價值就是讓基礎設施與業務邏輯完全解耦,兩者可以獨立演進。爲了實現這個核心價值,Sidecar 需要具備熱升級能力,以便升級時不會造成業務流量中斷,這對方案設計和技術實現的挑戰還是蠻大的。

我們的熱升級採用雙進程方案,先拉起新的 Sidecar 容器,由它與舊的 Sidecar 進行運行時數據交接,在新的 Sidecar 準備發接管流量後,讓舊的 Sidecar 等待一定時間後退出,最終實現業務流量無損。核心技術主要是運用了 Unix Domain Socket 和 RPC 的節點優雅下線功能。下圖大致示例了關鍵過程。

數據表現

公佈性能數據一不小心就會引發爭議和誤解,因爲性能數據的場景存在很多變量。比如,併發度、QPS、payload 大小等對最終的數據表現將產生關鍵影響。也正因如此,Envoy 官方從來沒有提供過本文所列出的這些數據,背後的原因正是其作者 Matt Klein 擔心引發誤解。值得強調的是,在時間非常緊迫的情形下,我們所落地的 Service Mesh 並非處於最優狀態,甚至不是最終方案(比如 Consumer 側存在兩次路由的問題)。我們之所以選擇分享出來,是希望讓更多的同行瞭解我們的進展和狀態。

本文只列出了 雙11 所上線核心應用中某一個的數據。從單機 RT 抽樣的角度,部署了 Service Mesh 的某臺機器,其 Provider 側的 RT 均值是 5.6ms,Consumer 側的是 10.36ms。該機器在 雙11 零點附近的 RT 表現如下圖所示:

沒有部署 Service Mesh 的某臺機器,Provider 側的均值爲 5.34ms,Consumer 側的則是 9.31ms。下圖示例了該機器在 雙11 零點附件的 RT 表現。

相比之下,Provider 側的 RT 在 Mesh 化前後增加了 0.26ms,Consumer 側則增加了 1.05ms。注意,這個 RT 差是包含了業務應用到 Sidecar,以及 Sidecar 處理的所有時間在內的,下圖示例說明了帶來時延增加的鏈路。

整體上,該核心應用所有上線了 Service Mesh 的機器和沒有上線 Service Mesh 的機器在某個時間段的整體均值數據做了對比。Provider 側 Mesh 化後的 RT 增加了 0.52ms,而 Consumer 側增加了 1.63ms。

在 CPU 和內存開銷方面,Mesh 化之後,Envoy 所消耗的 CPU 在所有核心應用上都維持在 0.1 核左右,會隨着 Pilot 推送數據而產生毛刺。未來需要藉助 Pilot 和 Envoy 之間的增量推送去對毛刺做優化。內存的開銷隨着應用的服務和集羣規模不同而存在巨大差異,目前看來 Envoy 在內存的使用上仍存在很大的優化空間。

從所有雙11 上線的核心應用的數據表現來看,Service Mesh 的引入對於 RT 的影響和帶來的 CPU 開銷是基本一樣的,而內存開銷則因爲依賴服務和集羣規模的不同而有相當大的差異。

展望

在雲原生的浪潮下,阿里巴巴借這波技術浪潮致力於打造面向未來的技術基礎設施。在發展的道路上將貫徹“借力開源,反哺開源”的發展思路,通過開源實現技術普惠,爲未來的雲原生技術在更大範圍的普及做出自己的貢獻。

接下來,我們的整體技術着力點在於:

  • 與 Istio 開源社區共同增強 Pilot 的數據推送能力。在阿里巴巴具備 雙11 這種超大規模的應用場景下,我們對於Pilot 的數據推送能力有着極致的要求,相信在追求極致的過程中,能與開源社區一道加速全球事實標準的共建。從阿里巴巴內部來看,我們目前拉通了與 Nacos 團隊的共建,將通過社區的 MCP 協議與 Nacos 對接,讓阿里巴巴所開源的各種技術組件能體系化地協同工作;

  • 以 Istio 和 Envoy 爲一體,進一步優化兩者的協議以及各自的管理數據結構,通過更加精煉、更加合理的數據結構去減少各自的內存開銷;

  • 着力解決大規模 Sidecar 的運維能力建設。讓 Sidecar 的升級做到可灰度、可監控和可回滾;

  • 兌現 Service Mesh 的價值,讓業務與技術設施能以更高的效率彼此獨立演進。

本文選自《不一樣的雙11,阿里巴巴經濟體雲原生實踐》電子書,點擊下載

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