Proxyless Service Mesh 在百度的實踐與思考

Service Mesh 已經在雲原生界火了很多年,大家的探索熱情依然不減。而最近一段時間 Proxyless Service Mesh 也開始進入大家的視野,比如:“Istio 官宣支持 gRPC Proxyless Service Mesh”,“Dubbo 3.0 引入 Proxyless Service Mesh 架構”。

那麼,什麼是 Proxyless Service Mesh?它和原來的 Proxy Service Mesh 有什麼區別和優缺點?落地場景又有哪些呢?本文將結合 Proxyless Service Mesh 在百度的落地實踐,帶你一探究竟。

什麼是 Proxyless Service Mesh

先來看下 Proxy Service Mesh,也就是最常見的 Service Mesh 架構,一般如下所示:

而 Proxyless Service Mesh 則是如下的架構:

Proxyless Service Mesh 的優缺點

如果簡單對比上述架構,不難得出 Proxyless 和 Proxy 模式的優缺點:

以上僅是一些直觀的分析,但當真正落地 Proxyless Service Mesh 的時候,會發現情況並不是我們想的那麼簡單。

百度的 Proxyless Service Mesh 實踐

Proxyless 第一階段

百度從 2018 年開始引入 Service Mesh,一開始是 Proxy 模式。到了 2020 年,我們在落地一些業務線的時候,發現 Proxy 模式很難在整個業務線全面鋪開:

因此我們開始引入如下的 Proxyless Service Mesh 模式:

這種方式的好處是:

Proxyless 第二階段

但是,第一階段方案,存在一些明顯的問題:

因此,到了 2021 年,我們設計並實現了一套 Proxyless/Proxy 統一架構的 Service Mesh:

無論是哪種模式,Envoy 都負責轉換配置,bRPC 負責配置執行,因此,所有的代碼都可以在 Proxy 和 Proxyless 模式下複用。

從業務場景上:

服務治理能力提升:

這個架構徹底解決了 Envoy 這個歷史包袱,讓 Service Mesh 輕裝上陣。

讓我們回過頭看一下前面說的 Proxyless 模式的兩個缺點是怎麼被解決的:

似乎這兩個缺點在我們的場景裏都沒有了:)

Proxyless 模式的真正優勢

Proxyless 模式的真正優勢是性能嗎?一開始我們都是這麼認爲的,但是隨着我們落地 Proxyless 模式的過程,我們才逐漸發現 Proxyless 模式的更多優勢。讓我們來看看一些場景吧:

請求級別控制參數的場景

比如我們要在 Service Mesh 中實現一致性哈希負載均衡,原來沒有 Service Mesh 的時候,用戶通過 RPC 框架提供的一個 set_request_code() 方法來設置請求級別哈希碼,RPC 框架可以確保同一個 request_code 的請求被調度到同一個後端實例。

在 Service Mesh 中如何實現這個需求呢?如果是 Proxy 模式,負載均衡是在 Sidecar 做的,Sidecar 需要獲取到這個 request_code。總不能讓用戶改代碼吧?那麼只能修改 RPC 框架,讓框架把 request_code 傳給 Sidecar。如圖所示:

怎麼傳給 Sidecar 呢?得在協議裏的某個字段中傳過去,比如 HTTP 協議可以在 header 中傳過去,那麼其它協議呢?每個協議都得找一個地方來傳這個字段,每個協議都得實現一遍這個邏輯。

所以在 Proxy 模式下,傳參這個事的實現成本 =(RPC 框架發送參數 +Sidecar 接收參數)* 協議數量。

那麼在 Proxyless 模式下呢?這個參數本來 RPC 框架就能拿到,所以傳參的實現成本 =0。

除了一致性哈希,類似的場景還有很多,比如請求級別超時控制、請求級別路由參數等,在這些場景下,Proxyless 模式完勝。

框架回調業務代碼的場景

比如用戶想實現一個自定義重試策略,RPC 框架在訪問一次後端服務之後,調用用戶代碼來判斷是否需要重試。一個典型的流程如下所求:

現在業務想要接入 Service Mesh,如果用 Proxy 模式,該如何實現用戶自定義重試策略呢?考慮以下方案:

在 Proxy 模式下,無論採用哪種方案,問題都很大。在 Proxyless 模式下呢?由於該功能 RPC 框架本來就支持,成本 =0。除了自定義重試策略,類似的場景還很多,比如自定義負載均衡策略、自定義 NamingService 等,在這些場景下,Proxyless 模式完勝。

動態多分片的場景

先解釋一下什麼叫動態多分片。多分片在搜索、推薦類業務是一個典型場景,也就是說一個服務的一個實例並不加載全量的數據,只加載一個分片的數據。客戶端調用此類服務時,需要將請求同時發送給不同分片的後端服務實例,獲取到每個分片的結果再進行彙總處理。動態多分片是指多個分片的服務組成一個分組,每次請求可以動態地選擇一組分片。之所以需要多個分組,一種場景是因爲數據發生擴容時,分片數會發生變化,爲了保證流量平滑遷移,會同時存在不同分片數量的分組;另一種場景是由於業務需要,不同的分組加載了不同業務屬性的數據,需要根據請求來動態確定調用哪個分組的服務。如下圖所示,分組 A 有 2 個分片,分組 B 有 3 個分片,而 k1、k2 則代表了不同的業務屬性。

在動態多分片場景下,業務代碼和 RPC 框架的一個簡化的交互流程如下:

之所以需要分兩個階段調用 RPC 框架,是因爲業務需要根據最終選定的分組和分片數量來拼裝業務的請求。

現在業務想要接入 Service Mesh,讓我們看看在 Proxy 模式下支持動態多分片的方案:

現在,讓我們看看 Proxyless 模式下支持動態多分片的方案:

雖然這個方案也有一定複雜性,但實現成本也不是很高,比 Proxy 模式的實現成本低多了。所以,在動態多分片場景,Proxyless 模式完勝。

服務可觀測場景

服務可觀測是 Service Mesh 的重點場景,我們來看一下這個場景下的一些需求吧:

  1. 用戶想實現分佈式 trace,需要將服務的入口流量和出口流量建立關聯,比如在處理 trace_id=x, span_id=y 的入口流量過程中,發出的出口流量,其 trace_id=x, parent_span_id=y。Sidecar: 這事我幹不了,得靠 RPC 框架。

  2. 用戶想把業務日誌和 RPC 日誌進行串聯,比如在處理 trace_id=x 的請求過程中,打印的業務日誌中都包含 trace_id=x 字段,這樣可以進行匯聚計算。Sidecar:這事我幹不了,得靠 RPC 框架和日誌庫打通。

  3. 用戶想監控請求處理過程的一些細化耗時,比如排隊時間、序列化反序列化時間。Sidecar:這事我幹不了,得靠 RPC 框架。

  4. 用戶想實現流量染色,比如將入口請求打上 k=v 標籤,然後由該請求觸發的整個調用鏈的請求都會帶上 k=v 標籤。Sidecar:這事我幹不了,得靠 RPC 框架。

  5. 用戶想針對業務代碼的耗時、cpu 使用進行分析,找出瓶頸。Sidecar:這事我幹不了……

爲什麼會出現這些情況呢?實現服務可觀測的最好方法就是深入服務內部,對於 Sidecar 來說,服務就是個黑盒,當然不好實現了。

所以,對於服務可觀測場景,Proxyless 模式完勝。

重新思考 Service Mesh 的本質

Service Mesh 的本質是 Sidecar 嗎?

誠然,Sidecar 是 Service Mesh 的一大賣點,比如方便支持多語言、和應用解耦,這可以讓用戶更方便地接入 Service Mesh。但是我們更應該關注 Service Mesh 給用戶帶來了什麼價值,如果用戶用了 Service Mesh 沒有收益,即使接入成本爲 0,用戶也會不接入的。

從用戶角度看,Service Mesh 帶來的是以下價值:

因此我認爲,Service Mesh 就是能讓服務間通信更可靠、更快、更透明、更靈活、更安全、更便於管理的基礎設施。

至於這個基礎設施是 Proxyless 還是 Proxy 模式,其實不是很重要。從實際業務場景出發,哪種模式更容易滿足業務需求,就用哪種方案。兩種模式各有自己的優勢場景,結合起來可以提供更好的服務。

Service Mesh 的本質是配置中心嗎?

有一種觀點認爲,Proxyless 模式不就是 RPC 框架 + 配置中心嗎?Proxy 模式不就是一個 7 層代理 + 配置中心嗎?這玩意很多年前就有了。

但是,Service Mesh 的控制平面,不能簡單看作配置中心。配置中心僅僅是簡單地將配置文件或者配置項進行下發,並不感知配置的實際含義。

以 Istio 爲代表的控制平面,實際上是定義了 Service Mesh 的能力標準,比如各種路由、負載均衡策略等。如果只是做了一個簡單的 RPC 框架,暴露了幾個超時參數到配置中心來控制,那不叫 Service Mesh,因爲沒有實現 Service Mesh 的標準能力。即使 RPC 框架把 Service Mesh 的標準能力都實現了,但是沒有統一的協議和配置格式,不同的框架的配置方式五花八門,通信協議互相割裂,那也不能算 Service Mesh。

所以說,Service Mesh 是一組服務間通信的能力標準,實現了這些標準,就可以稱之爲 Service Mesh。

Service Mesh 未來展望

從目前趨勢看來,Istio 仍然會作爲 Service Mesh 控制平面的首選。儘管 Istio 的 CRD 對用戶也不是很友好,但是 Istio 定義的 Service Mesh 標準體系目前仍是最完整的,也獲得了最廣泛的數據平面的支持。

而數據平面,則可能出現百花齊放的場景,畢竟業務場景非常多樣,有的看重靈活性,有的看重性能,有的看重安全,那麼就能催生不同的數據平面實現方案。Envoy 仍然會作爲 Proxy 模式的主流選擇,但各 RPC 框架也不甘於只做瘦客戶端,將會繼續發展自己的 Proxyless 方案,讓 Service Mesh 能落地到更多的業務場景之中。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8T7XI6jQfZunwVYDaDHvLw