大報文之道:優化策略與實踐

寫在前面

在做正常的需求開發時,當我們提供了一個接口或是調用別人接口時,我們需要考慮接口除了正常的邏輯處理外,還需要考慮接口能接收報文的上限,性能,響應時間等一系列非功能性需求。如果不注意這些問題,就可能在某一天的某個時刻收到一系列系統告警,嚴重者甚至導致系統不可用,引發線上事故。如涉及明細列表相關的接口中沒考慮明細的上限,某一時刻上游下發了一個大明細從而可能就引發了上述的問題。這就是日常所說的大報文,其特點就是單次請求的數據量特別大,超出了系統正常的處理能力,需要耗費較長的時間才能處理完成。面對此類非功能性需求,在日常的開發中如何去避免和解決呢,今天主要帶來的是主子模型下,明細行過大的處理。

一、識別大報文

大報文一般來源於批量接口或單個接口中入參爲主子模型的接口,如果是消息隊列,則是一次發送的消息中消息報文裏發送了多條業務消息或是消息的報文結構也爲主子模型的消息導致。

批量接口模型
Response<List<T>> method(List<T> list);

單個接口入參爲主子模型
T method(OrderInfo orderInfo);

class OrderInfo{
   List<OrderDetailInfo> orderDetailInfoList;
}

class OrderDetailInfo{
}


對於批量接口或是消息隊列裏發送了多條業務消息的情況在這不做過多闡述,通常的邏輯是改爲分批調用或分批發送消息就可以。但對於主子模型的報文,如果是正常的業務,則不能要求業務不要這麼來下發,尤其是TOB類業務,因此需要從技術的角度加以解決。

 

二、解決大報文

這裏主要討論針對單個接口,裏面的參數是主子模型的場景,因這類場景在日常的開發中最常見,用得很普遍。





 



第一點,先從AppA側看可優化的點:

從調用方AppA的角度,如果傳入的消息報文過大,導致AppB處理失敗,那麼對AppA來說也是失敗,爲了確保調用的成功,從AppA的角度看,對其可做如下一些優化。

首先,AppA在調用AppB時,可以和AppB約定接口的超時時間。超時後,AppA需要有重試機制,而對應的AppB需要保證接口執行的冪等性。在超時時間的設置上,如果大報文是個極少發生的場景,還可以考慮對超時時間進行動態設置,針對大報文的請求,把相應的超時時間適當加長,確保調用的成功。

其次,爲了保證數據報文能快速達到AppB,AppA在請求調用AppB時,可以對報文進行壓縮,確保網絡傳輸能以最快的速度把數據報文發送到AppB。

 





 



第二點,從AppB側看可優化的點:

而從AppB側來看,需要從業務邏輯裏分析耗時的邏輯,一般來說這個分析比較靠譜的是壓測,搭建一套與線上環境類似的環境,模擬線上場景進行壓測,壓測出耗時的業務邏輯,針對耗時的業務邏輯進行優化。在這裏由於我們的入參是主子模型的,按經驗來講,耗時點一般位於處理明細的邏輯裏,所以可以重點關注明細處理相關邏輯。

首先,AppB在接收到請求後,對請求報文中的參數做基本的業務邏輯校驗,校驗通過後,爲了能快速的響應調用方,可以把整個業務處理邏輯轉入異步進行處理,確保調用方不超時。業務邏輯進入異步處理後還可能處理的時間比較耗時,此時可根據業務的時效性再進行處理。

其次,在AppB內,如果通過壓測最後的耗時的確是在對明細的處理上,那麼可以考慮對明細進行分批處理,不同的處理邏輯對於分批大小後得到的處理時長是不一樣的,需要經過多輪調整參數的壓測,找到適合自己業務邏輯的參數值。在我經歷的大明細保存數據庫實踐中,不分批一次直接保存1萬條明細到數據庫與分批保存數據庫及每批次的大小不同最終導致所有明細保存完數據庫的時間也是有天壤之別的。



數據條數 保存方案 每次保存條數(條) 平均耗時(毫秒)
10000條 一次保存 10000 159005
10000條 分批保存 200 15363
10000條 分批保存 500 18720

再次,在確定了耗時的業務邏輯後,針對耗時的業務邏輯可以啓用多線程處理。在使用多線程時,核心線程數的設置建議與CPU的核數相同,確保有較好的性能輸出。在本文所述的此類場景中,用到了多線程就需要對批量的明細進行分批,結合上面說的不同的批次大小會有不同的性能表現,所以設置的參數建議還是通過壓測獲取,確保參數的最優。





 

還是剛纔保存10000條明細進數據庫的案例,在使用多線程並結合分批保存的方案後,在相同硬件及網絡條件,單次保存的耗時降低至1秒左右,最終所有明細保存完成的總耗時在10秒左右,此時應用的壓力有所上升,但數據庫的壓力幾乎沒什麼變化。



數據條數 保存方案 每次保存條數(條) 單次平均耗時(毫秒) 總耗時(毫秒)
10000條 分批+多線程保存 100 1103 10184

三、經驗沉澱

在進行大報文優化時,沒有一個通用可行的方法能解決各類問題,本文闡述的僅是在主子模型下,明細過大的一些可行方法及在實際中的實踐。而在實際的開發中,結合具體的業務場景,大報文的處理會更加複雜,需要結合具體業務具體分析。但我們日常積累的分批,多線程,異步,調整超時時間等手段都可在解決大報文中發揮各自應有的作用,可結合具體場景進行多種技術手段的綜合運用,最終把大報文場景消滅在上線前,確保生產環境的穩定、可靠。

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