API接口性能優化總結
摘要
在web開發過程中,經常會遇到接口RT高的情況,除了通過監控事后優化的方式,我們還需要掌握一些常用的手段,避免寫出慢的接口。從前端發起調用到后端一般經過網關層、應用層、存儲層。每一層都可以優化,本篇文章主要是應用層優化。
常見性能優化思路
從理論上分析,性能優化手段通常有
批量
- 請求數據庫,我們一般會用in,提高數據庫查詢效率
- 調用外部服務,我們也需要要求依賴方提供批量接口,避免多次網絡請求
- 批量查詢的id數量也不宜過多
之前在sql IN一文中分析過,IN 的數量太多時,性能會下降。同樣服務間調用,數據量過大,帶寬占用大。所以這時候需要分批調用。
List<String> res= Lists.partition(ids, 200).parallelStream()
.flatMap(batch -> mServiceA.batchGetA(batch).stream())
.collect(Collectors.toList());
并行/并發處理,利用多線程可以提高效率
比如接口中需要請求多個外部接口/數據庫,相互之間無依賴,因為這種操作都是IO操作,可以由順序執行改為并行執行,充分利用cpu處理能力,如
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> mServiceA.getA());
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> mServiceB.getB());
CompletableFuture.allOf(a,b).join();
異步,非強依賴的調用可以通過異步化處理
異步,分為讀寫。比如寫是弱依賴,可以用 @Async 或者其他操作。
如果是讀,不是必須的數據,也需要加上超時處理,因為外部調用有網絡原因,都是不可靠的
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> mServiceA.getA());
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> mServiceB.getB());
try {
CompletableFuture.allOf(a, b).get(1000, TimeUnit.MILLISECONDS);
} catch (Exception ex) {
if (!a.isDone()) {
}
if (!b.isDone()) {
}
}
減少數據處理量
eg. 拉取外部數據,全量的循環去拉,增量的使用事件通知機制,這樣可以減少數據處理量
避免深度分頁
數據庫的深度分頁性能比較差,需要在業務上避免深度分頁
緩存
緩存本質上就是從讀取速度快的設備中直接獲取數據。通過空間來換時間。對于DB中的數據可以緩存,對于外部服務的數據同樣可以緩存
使用多級緩存,可以最大限度提升性能。