復雜并發場景下的并發調度模型在轉轉的演進之路
一、問題背景
設想,打開一個 APP,我們會看到什么?答案是: 內容信息 。
例如當我們打開轉轉 APP 時,目光所及的首頁、商品列表頁、商品詳情頁...以上我們簡稱為信息聚合場景。在電商 APP 中,此類信息聚合場景往往需要 聚合 多種數據源才能完成最終渲染,這也意味著在微服務架構中,服務端響應一次用戶請求需要聚合 N 個內部 RPC 請求響應的數據才能完成最終響應。
而為了盡快響應用戶請求,往往需要通過某些方式異步發起多個 RPC 請求來獲取結果數據,我們把這樣的過程稱為并發場景。
二、復雜并發場景釋義
2.1 簡單并發場景
較為 簡單 的信息聚合場景,一次信息聚合過程只需要 N 個 相互獨立 的 RPC 結果即可。如下圖所示:
2.2 復雜并發場景
較為 復雜 ,但卻常見的重要信息聚合場景。通常意味著響應一次用戶請求的過程:1,需要聚合多個 RPC 響應結果;2,內部多個 RPC 請求之間 存在相互依賴關系 ,如下圖所示:D 的 request 依賴 A、B 的 response;E 的 request 依賴 C、D 的 response;...
三、分組并發調度模型演進
3.1 簡單異步并發調度
為了盡量提升服務端的請求響應速度,我們可以有一些簡單的方式,如:
基于 Future 等基礎能力,在一次用戶請求的處理過程中,異步執行沒有前后依賴關系的 RPC 過程。
這種方式通常更 適用于簡單并發場景 ,而復雜并發場景下怎么辦呢?
自然而然,我們很容易想到一個方式:分組并發調度。
3.2 分組并發調度
分組并發調度主要適用于一次用戶請求處理過程需要聚合多個存在前后依賴關系的 RPC 查詢結果的復雜并發場景中,通常我們會使用如下方案:
1, 分組 :將所有 RPC 查詢過程按照依賴關系分組。如:沒有前置依賴的 RPC 過程認為是第一組;依賴第一組的 RPC 過程認為是第二組;依此類推...
2, 調度 :基于 CompleteFuture、Future 等基礎能力,依次從第一組開始并發執行組內的 RPC 過程。即:組間同步、組內異步。
為了提升開發效率,我們可以基于 Future 等基礎能力重新封裝自己的分組并發調度工具,甚至集成并發治理等方面的能力,如:細粒度的超時調控、熔斷降級機制,以大幅度降低治理工作成本。
四、自驅動并發調度模型演進
4.1 一個優化耗時的小目標及其實現
在 2020 年 Q2,轉轉基礎生態有這么一個 OKR:實現全平臺核心接口平均耗時穩定降低到 90ms 以下。不可忽略的背景是彼時接口耗時在 120ms 上下,且受下游服務方影響,每周呈現 10ms 的上漲趨勢。為了完成這個不太可能的目標,我們做了 這些事情 :
1.分析接口單位貢獻值 :主要根據接口 QPS,分別分析單接口每降低 10ms 的響應時間對全局響應的貢獻值,確定優化方向。
2.理解每一毫秒的耗時 :假設從監控平臺我們可以看到某個接口耗時為 200ms,但具體耗時在哪是不明確的。為此,我們在每個接口的內部執行邏輯,從代碼行的維度監測耗時,嘗試去完全理解每一毫秒。
3.并發調度調整 :基于上述準備,進行接口耗時優化。期間我們發現嚴格的分組并發調度模型并不能達到最佳調度,為此我們又破壞了原本的分組模型,將一些沒有前后依賴的長耗時 RPC 過程單獨提取出來做全局異步調度。
在 Q2 結束,全平臺核心接口平均耗時降低到 85ms,超額完成了既定目標。
4.2 下一步的疑惑
隨著耗時優化目標的完成,我們產生了一些這樣的疑惑:
1.開發維護工作依舊 繁瑣 :復雜并發場景中,隨著業務迭代,代碼腐化嚴重。一個小需求的迭代可能需要太多的前置熟悉代碼的時間。
2.接口耗時優化工作 周而復始 :回想過去,每到一定的時間(例如一兩周、一兩個月),需要花費時間去調整并發模型,優化組織分組邏輯以盡可能消除業務迭代帶來的影響。
3.分組并發調度模型的 折中 :結合上述目標的完成過程,我們為了性能而應用分組并發調度模型后又為了性能破壞既定模型。
信息聚合場景的接口耗時優化,
下一步該怎么做?
4.3 對問題的重新思考以及自驅動并發調度模型的誕生
4.3.1 重新思考
回想以往,我們做的是什么?不外乎:編織一幅圖。
上圖示意一次用戶請求(如商品列表頁搜索)的內部 RPC 聚合過程,一個最簡單的聚合節點等同于一次 RPC 請求過程。
回首我們的開發工作,會發現做的事情其實是:
1. 畫點 :例如商列需要展示活動信息,此時就會新增一個查詢活動信息的 RPC 聚合節點。
2.連線 :我們依據依賴關系將可以同時并發查詢的節點放置于同一組。
3.畫圖 :組織各組的并發調度、數據同步、并串行驅動下一組。
整個過程概括起來就是: 點動成線,線動成面 。 可能這正是對復雜并發場景下一系列表面問題背后的 更深層
的一種描述。
4.3.2 自驅動并發調度模型
基于以上思考,可以發現在業務開發中:
1.業務邏輯強相關的增量邏輯在于 “點” 。
2.業務邏輯弱相關的重復工作成本在于 “連線” 、在于 “圖的編織” 。
那么,有沒有一種可能:開發者僅僅關心“點”,由額外的框架能力來處理“線”與“圖”?
即是“點動成線,線動成面”中 “動”的工作由框架能力自動化支持。
于是,自驅動并發調度模型基于此愿景而誕生,整體設計方向如下:
1.開發模式的聚焦:實現面向節點行為的開發方式
2.框架能力的聚焦:框架聚焦于任意兩點之間的自動化連線能力,從而實現全圖的自動編織。
五、結語
本文的講述側重于并發調度模型演進的思考過程,講述了基于對問題的理解再理解的探索過程去尋找當前最佳解決方案的思路,也是轉轉公司復仇者聯盟技術生態系列之奧創組件的由來。