之前工作中,遇到一個504
超時問題。原因是因為接口耗時過長,超過nginx
配置的10
秒。然后 真槍實彈搞了一次接口性能優化,最后接口從11.3s
降為170ms
。本文將跟小伙伴們分享接口優化的一些通用方案。
1. 批量思想:批量操作數據庫
優化前:
//for循環單筆入庫
for(TransDetail detail:transDetailList){
insert(detail);
}
優化后:
batchInsert(transDetailList);
打個比喻:
打個比喻:假如你需要搬一萬塊磚到樓頂,你有一個電梯,電梯一次可以放適量的磚(最多放
500
), 你可以選擇一次運送一塊磚,也可以一次運送500
,你覺得哪種方式更方便,時間消耗更少?
2. 異步思想:耗時操作,考慮放到異步執行
耗時操作,考慮用 異步處理 ,這樣可以降低接口耗時。
假設一個轉賬接口,匹配聯行號,是同步執行的, 但是它的操作耗時有點長 ,優化前的流程:
為了降低接口耗時,更快返回,你可以把匹配聯行號移到 異步處理 ,優化后:
- 除了轉賬這個例子,日常工作中還有很多這種例子。比如: 用戶注冊成功后,短信郵件通知,也是可以異步處理的 ~
- 至于異步的實現方式, 你可以用線程池,也可以用消息隊列實現 。
3. 空間換時間思想:恰當使用緩存。
在適當的業務場景,恰當地使用緩存,是可以大大提高接口性能的。緩存其實就是一種 空間換時間的思想 ,就是你把要查的數據,提前放好到緩存里面,需要時, 直接查緩存,而避免去查數據庫或者計算的過程 。
這里的緩存包括:Redis
緩存,JVM
本地緩存,memcached
,或者Map
等等。我舉個我工作中,一次使用緩存優化的設計吧,比較簡單,但是思路很有借鑒的意義。
那是一次轉賬接口的優化, 老代碼 ,每次轉賬,都會根據客戶賬號,查詢數據庫,計算匹配聯行號。
因為每次 都查數據庫,都計算匹配,比較耗時 ,所以 使用緩存 ,優化后流程如下:
4. 預取思想:提前初始化到緩存
預取思想很容易理解,就是 提前把要計算查詢的數據,初始化到緩存 。如果你在未來某個時間需要用到某個經過復雜計算的數據, 才實時去計算的話,可能耗時比較大 。這時候,我們可以采取預取思想, 提前把將來可能需要的數據計算好,放到緩存中 ,等需要的時候,去緩存取就行。這將大幅度提高接口性能。
我記得以前在第一個公司做視頻直播的時候,看到我們的直播列表就是用到 這種優化方案 。就是啟動個任務, 提前把直播用戶、積分等相關信息,初始化到緩存 。
5. 池化思想:預分配與循環使用
大家應該都記得, 我們為什么需要使用線程池 ?
線程池可以幫我們管理線程,避免增加創建線程和銷毀線程的資源損耗。
如果你每次需要用到線程,都去創建,就會有增加一定的耗時,而線程池可以重復利用線程,避免不必要的耗時。 池化技術不僅僅指線程池,很多場景都有池化思想的體現,它的本質就是 預分配與循環使用 。
比如TCP
三次握手,大家都很熟悉吧,它為了減少性能損耗,引入了Keep-Alive長連接
,避免頻繁的創建和銷毀連接。當然,類似的例子還有很多,如數據庫連接池、HttpClient
連接池。
我們寫代碼的過程中, 學會池化思想 ,最直接相關的就是使用線程池而不是去new
一個線程。
-
接口優化
+關注
關注
0文章
4瀏覽量
1347
發布評論請先 登錄
相關推薦
評論