一次接口的性能優化之旅

架構互聯高可用 2024-04-30 08:04:44
01 引言在今年的敏捷團隊建設中,我通過Suite執行器實現了一鍵自動化單元測試。Juint除了Suite執行器還有哪些執行器呢?由此我的Runner探索之旅開始了!

在項目開發過程中,我們經常會遇到接口響應慢的問題。這不僅影響了用戶體驗,還可能降低了系統的吞吐量。爲了提高接口性能,我們需要對整個系統進行全面的優化,包括代碼層面、數據庫、緩存、異步處理等方面。本文將分享一個接口性能優化之旅,希望能幫助大家掌握Pfinder使用、JSF異步調用等優化技巧,提升接口性能和定位問題的能力。

02 現狀診斷 理解,首先 MCube 會依據模板緩存狀態判斷是否需要網絡獲取最新模板,當獲取到模板後進行模板加載,加載階段會將産物轉換爲視圖樹的結構,轉換完成後將通過表達式引擎解析表達式並取得正確的值,通過事件解析引擎解析用戶自定義事件並完成事件的綁定,完成解析賦值以及事件綁定後進行視圖的渲染,最終將目標頁面展示到屏幕。

UMP診斷:

Max:10s

T99:1000ms

經常可用率下降

Pfinder診斷:

問題1:循環調用RPC 120次=1441ms

問題2:查詢DB 286ms

問題3:未知操作 2000ms+

03 問題定位以及性能優化 理解,首先 MCube 會依據模板緩存狀態判斷是否需要網絡獲取最新模板,當獲取到模板後進行模板加載,加載階段會將産物轉換爲視圖樹的結構,轉換完成後將通過表達式引擎解析表達式並取得正確的值,通過事件解析引擎解析用戶自定義事件並完成事件的綁定,完成解析賦值以及事件綁定後進行視圖的渲染,最終將目標頁面展示到屏幕。如何解決Pfinder顯示耗時不全問題:-> 手動完善全程跟蹤上報

集成Pfinder SDK:

<!-- 引用 PFinder SDK 庫 --><dependency> <groupId>com.jd.pfinder</groupId> <artifactId>pfinder-profiler-sdk</artifactId> <version>1.2.2-FINAL</version></dependency>使用注解:@PFTracing

上報效果

定位問題和進行代碼分析

這段代碼的目的是從一個名爲waveInfos的字符串列表中,篩選出已經包含在另一個名爲sendDPackageCodes的字符串列表中的元素,並將這些重複的元素放入一個新的列表repeatResult中。然後,它從waveInfos中排除這些重複的元素,將剩余的元素放入另一個新的列表showPackages中。這兩個列表最終被用于前端顯示或進一步處理。簡而言之,這段代碼的作用是去重並篩選出尚未處理的數據。

通過現象查看此處代碼耗時占總耗時進一半左右,因此判斷集合數據非常多,導致數據計算耗時較長。通過日志打印發現:waveInfos=3000+,sendDPackageCodes=7000+,因此可以看出兩個集合因爲數據過大導致耗時較長。

代碼優化:使用Set進行處理

優化效果:2000ms -> 6ms如何解決RPC批量調用問題 -> 使用JSF異步調用 同步異步方案比較

JSF異步調用使用

第一步:如果存在同步bean,爲了不影響同步bean可以注入新的異步bean。需要

注意:jsf 這邊相同接口 別名 最多支持3個// 同步bean@Autowiredprivate XxxxxApi xxxxApi;// 異步實現bean,(jsf 這邊相同接口 別名 最多支持3個)@Autowiredprivate XxxxxApi xxxxAsyncApi;<!-- 【異步】路由查詢班次單號明細 --><jsf:consumer id="xxx" interface="xxx" protocol="jsf" alias="xx" timeout="xxx" retries="0" check="false"> <jsf:method name="方法名稱" async="true"/></jsf:consumer>第二步:使用RpcContext調用,返回CompletableFuture對象// Rpc代理類 需要返回CompletableFuture 對象public CompletableFuture<CommonDto<PageDto>> queryWaybillDetailByBusinessIdByAsync() { // 發起方法請求 return RpcContext.getContext().asyncCall(() -> xxxxAsyncApi.method());;第三步:調用處任意地方,獲取future返回結果,需要指定超時時間public <T> T getResultDefaultTimeOut(CompletableFuture<T> future) { try { return future.get(10, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new RuntimeException(e); }} 優化效果:1400ms -> 200ms04 最終效果和未解決問題 理解,首先 MCube 會依據模板緩存狀態判斷是否需要網絡獲取最新模板,當獲取到模板後進行模板加載,加載階段會將産物轉換爲視圖樹的結構,轉換完成後將通過表達式引擎解析表達式並取得正確的值,通過事件解析引擎解析用戶自定義事件並完成事件的綁定,完成解析賦值以及事件綁定後進行視圖的渲染,最終將目標頁面展示到屏幕。優化前優化後

05 總結 理解,首先 MCube 會依據模板緩存狀態判斷是否需要網絡獲取最新模板,當獲取到模板後進行模板加載,加載階段會將産物轉換爲視圖樹的結構,轉換完成後將通過表達式引擎解析表達式並取得正確的值,通過事件解析引擎解析用戶自定義事件並完成事件的綁定,完成解析賦值以及事件綁定後進行視圖的渲染,最終將目標頁面展示到屏幕。 接口性能優化是一個涉及多個方面的過程,需要從代碼層面、數據庫、緩存、異步處理等多個維度進行優化。在這個過程中,我們需要不斷診斷瓶頸、嘗試優化手段,並結合實際情況進行調整。希望通過本文的分享,大家能掌握接口性能優化的方法和技巧,提高接口性能,提升用戶體驗。活動介紹:GIAC全球互聯網架構大會

本文由高可用架構轉載。技術原創及架構實踐文章,歡迎通過公衆號菜單「聯系我們」進行投稿

0 阅读:0

架構互聯高可用

簡介:感謝大家的關注