1、背景
購物車面臨的挑戰:
1)新業務:隨著業務形態的豐富,購物車在不斷支持各種新業務,依賴的外部介面也隨之增加;
2)下沉:一些前端呼叫的介面下沉到購物車中臺;
3)前置:結算流程很多業務前置到購物車中,如優惠券、京豆;
4)擴容:為改善用戶體驗購物車可容納的商品數量在不斷增長;
這些導致購物車依賴的RPC介面數量及分頁呼叫次數都在不斷增加,購物車作為交易流程開端,本身流量較大,在業務復雜化的背景下,如何提高性能保證用戶體驗,成為購物車面臨的較大挑戰,
2、全異步化改造方案
通過增加服務器資源雖然能在一定程度上解決問題,但會帶來較大的成本開銷,也與工匠精神相悖,能否通過技術手段提升性能呢?通過分析,異步化改造成為解決這一問題的有效手段,
1)不同RPC并行
購物車依賴介面達幾十個,各介面間存在復雜依賴關系,必須先梳理各介面間依賴,識別哪些可以并行,然后將原有代碼拆分為兩部分:RPC異步請求和結果處理,按照依賴關系,讓RPC最大限度并行執行,減少在結果處理階段異步回應等待時間,從而達到提升性能的目的,
2)批量介面多分頁并行
購物車依賴介面多為批量介面,且單次呼叫有資料量限制,需將資料拆分為多個分頁呼叫,那么多個分頁間也可以并行,改造中封裝了異步分頁工具,使業務層對分頁邏輯無感知,異步工具自動將超過介面上限的資料拆分為多個分頁并行呼叫,提升單介面回應速度,
3)底層采用JSF異步呼叫
異步呼叫基于京東RPC框架JSF,推薦使用1.7.5以后版本,支持CompletableFuture,
3、問題及解決
異步化改造的總體方案并不復雜,但是在實際落地程序中,遇到了很多細節問題:
1)例外重試需精細化
同步呼叫時,如果超時會重新呼叫,改為異步后重試會失效,因為在呼叫時一般不會報錯,需要在結果處理階段獲取異步回應超時后,再進行重試,
另外,多分頁并行時,當某一頁請求超時后,應該只重試出錯的分頁,底層對分頁呼叫進行了封裝,上層業務代碼在獲取資料時無法感知是哪一頁超時,所以必須在異步呼叫時將現場資訊保存在包裝類中,一起回傳給業務層,在Get資料超時后,單獨重試出錯的分頁,
發生例外時,并不是所有情況都需要重試,當遇到限流等例外時,不能進行重試,底層工具需要自動過濾限流例外,當然也支持自定義規則,
2)異步RPC監控更復雜
底層RPC耗時監控需要拆分為兩部分,在分頁呼叫時記為開始時間,在異步結果到達后,記為結束時間,如果呼叫例外或Get超時,需要標記本次呼叫失敗,對于重試同樣需要記錄呼叫耗時,且正常呼叫與重試呼叫需分開記錄,
除了需要監控RPC耗時外,還需要監控結果處理階段Get等待時長,這個時間才是真正對應用性能有影響的時間,由于底層是分頁呼叫,所以業務呼叫次數和底層RPC呼叫次數并不相同,
3)分頁異步結果不能合并,否則無法獲取例外Provider資訊
底層異步呼叫結果,必須通過包裝類原樣回傳給上層,除了上邊提到的需要單分頁重試外,另一個原因是必須保留異步結果,在分頁超時后才能輸出超時的Provider資訊,這是由于Provider資訊依賴JSF框架的JSFCompletableFuture,如果在底層合并結果,會導致資訊丟失,
4)每頁超時時間需單獨控制
分頁呼叫程序如上圖所示,在結果處理時,每頁Get超時時間需要單獨控制,因為獲取結果是順序進行,獲取后邊的分頁時,前邊分頁等待的時間也應計算在內,以保證整個獲取結果的時間不超過單個分頁的最大超時時間,計算公式如下:
超時=RPC超時時間 > (當前時間-異步呼叫開始時間) ? RPC超時時間 – (當前時間-異步呼叫開始時間) : 0
5)分頁均衡
為避免最后一頁資料過少造成資料傾斜,需要將請求資料均分到每一頁,以最大限度提高整個請求的性能,
4、收益
改造完成后購物車核心介面耗時減少30%,保證用戶體驗,節省大量服務器資源,后續增加新的RPC介面時,只要處在呼叫拓撲的非關鍵路徑上,對購物車性能沒有太大影響,另外,容量增加時除少數不能分頁呼叫的介面外,對性能影響已經比較小,
作者:京東零售 王利輝 梁奉龍
內容來源:京東云開發者社區
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/553181.html
標籤:其他
上一篇:關于微信小程式原生組件與uniApp混合開發程序遇到的問題與解決方式
下一篇:返回列表