一、引言
在項目開發過程中,我們經常會遇到接口響應慢的問題。這不僅影響了用戶體驗,還可能降低了系統的吞吐量。爲了提高接口性能,我們需要對整個系統進行全面的優化,包括代碼層面、數據庫、緩存、異步處理等方面。本文將分享一個接口性能優化之旅,希望能幫助大家掌握Pfinder使用、JSF異步調用等優化技巧,提升接口性能和定位問題的能力。
二、現狀診斷
三、問題定位以及性能優化
如何解決Pfinder顯示耗時不全問題:-> 手動完善全程跟蹤上報
<!-- 引用 PFinder SDK 庫 -->
<dependency>
<groupId>com.jd.pfinder</groupId>
<artifactId>pfinder-profiler-sdk</artifactId>
<version>1.2.2-FINAL</version>
</dependency>
這段代碼的目的是從一個名爲waveInfos
的字符串列表中,篩選出已經包含在另一個名爲sendDPackageCodes
的字符串列表中的元素,並將這些重複的元素放入一個新的列表repeatResult
中。然後,它從waveInfos
中排除這些重複的元素,將剩餘的元素放入另一個新的列表showPackages
中。這兩個列表最終被用於前端顯示或進一步處理。簡而言之,這段代碼的作用是去重並篩選出尚未處理的數據。
通過現象查看此處代碼耗時佔總耗時進一半左右,因此判斷集合數據非常多,導致數據計算耗時較長。通過日誌打印發現:waveInfos=3000+,sendDPackageCodes=7000+,因此可以看出兩個集合因爲數據過大導致耗時較長。
代碼優化:使用Set進行處理
優化效果:2000ms -> 6ms
如何解決RPC批量調用問題 -> 使用JSF異步調用
同步異步方案比較
優劣勢 | 異步調用 | 同步調用 |
優勢 | 提高系統的併發性能 | 簡單直觀 |
| 提高系統的響應速度 | 錯誤處理方便 |
| 節約資源 | |
劣勢 | 複雜性 | 阻塞線程 |
| 可讀性差 | 響應速度慢 |
JSF異步調用使用
第一步:如果存在同步bean,爲了不影響同步bean可以注入新的異步bean。需要
注意:jsf 這邊相同接口 別名 最多支持3個
// 同步bean
@Autowired
private XxxxxApi xxxxApi;
// 異步實現bean,(jsf 這邊相同接口 別名 最多支持3個)
@Autowired
private 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 -> 200ms
五、最終效果和未解決問題
優化前優化後
問題 | 優化前 | 優化後 | 方案 |
總耗時 | 3800ms | 500ms | |
rpc循環調用 | 1400ms | 200ms | JSF異步調用(N次耗時變一次最大耗時) |
數據笛卡爾積處理 | 2000ms | 6ms | list包含操作變set包含操作 |
數據庫操作 | 100ms | 100ms | 數據庫批量查詢,此期不處理 |
未知操作 | 150ms | 150ms | 非業務代碼,懷疑是sql查詢後結果處理,目前無法跟蹤和處理,此期不處理 |
六、總結
接口性能優化是一個涉及多個方面的過程,需要從代碼層面、數據庫、緩存、異步處理等多個維度進行優化。在這個過程中,我們需要不斷診斷瓶頸、嘗試優化手段,並結合實際情況進行調整。希望通過本文的分享,大家能掌握接口性能優化的方法和技巧,提高接口性能,提升用戶體驗。