精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

接口性能優化實戰:從20s到500ms,三招搞定

開發 新聞
上周我優化了一下線上的批量評分查詢接口,將接口性能從最初的20s,優化到目前的500ms以內。總體來說,用三招就搞定了。

?前言

接口性能問題,對于從事后端開發的同學來說,是一個繞不開的話題。想要優化一個接口的性能,需要從多個方面著手。

本文將會接著接口性能優化這個話題,從實戰的角度出發,聊聊我是如何優化一個慢查詢接口的。

上周我優化了一下線上的批量評分查詢接口,將接口性能從最初的20s,優化到目前的500ms以內。

總體來說,用三招就搞定了。

到底經歷了什么?

案發現場

我們每天早上上班前,都會收到一封線上慢查詢接口匯總郵件,郵件中會展示接口地址、調用次數、最大耗時、平均耗時和traceId等信息。

我看到其中有一個批量評分查詢接口,最大耗時達到了20s,平均耗時也有2s。

用skywalking查看該接口的調用信息,發現絕大數情況下,該接口響應還是比較快的,大部分情況都是500ms左右就能返回,但也有少部分超過了20s的請求。

這個現象就非常奇怪了。

莫非跟數據有關?

比如:要查某一個組織的數據,是非常快的。但如果要查平臺,即組織的根節點,這種情況下,需要查詢的數據量非常大,接口響應就可能會非常慢。

但事實證明不是這個原因。

很快有個同事給出了答案。

他們在結算單列表頁面中,批量請求了這個接口,但他傳參的數據量非常大。

怎么回事呢?

當初說的需求是這個接口給分頁的列表頁面調用,每頁大小有:10、20、30、50、100,用戶可以選擇。

換句話說,調用批量評價查詢接口,一次性最多可以查詢100條記錄。

但實際情況是:結算單列表頁面還包含了很多訂單。基本上每一個結算單,都有多個訂單。調用批量評價查詢接口時,需要把結算單和訂單的數據合并到一起。

這樣導致的結果是:調用批量評價查詢接口時,一次性傳入的參數非常多,入參list中包含幾百、甚至幾千條數據都有可能。

現狀

如果一次性傳入幾百或者幾千個id,批量查詢數據還好,可以走主鍵索引,查詢效率也不至于太差。

但那個批量評分查詢接口,邏輯不簡單。

偽代碼如下:

public List<ScoreEntity> query(List<SearchEntity> list) {
//結果
List<ScoreEntity> result = Lists.newArrayList();
//獲取組織id
List<Long> orgIds = list.stream().map(SearchEntity::getOrgId).collect(Collectors.toList());
//通過regin調用遠程接口獲取組織信息
List<OrgEntity> orgList = feginClient.getOrgByIds(orgIds);

for(SearchEntity entity : list) {
//通過組織id找組織code
String orgCode = findOrgCode(orgList, entity.getOrgId());

//通過組合條件查詢評價
ScoreSearchEntity scoreSearchEntity = new ScoreSearchEntity();
scoreSearchEntity.setOrgCode(orgCode);
scoreSearchEntity.setCategoryId(entity.getCategoryId());
scoreSearchEntity.setBusinessId(entity.getBusinessId());
scoreSearchEntity.setBusinessType(entity.getBusinessType());
List<ScoreEntity> resultList = scoreMapper.queryScore(scoreSearchEntity);

if(CollectionUtils.isNotEmpty(resultList)) {
ScoreEntity scoreEntity = resultList.get(0);
result.add(scoreEntity);
}
}
return result;
}

其實在真實場景中,代碼比這個復雜很多,這里為了給大家演示,簡化了一下。

最關鍵的地方有兩點:

  • 在接口中遠程調用了另外一個接口
  • 需要在for循環中查詢數據

其中的第1點,即:在接口中遠程調用了另外一個接口,這個代碼是必須的。

因為如果在評價表中冗余一個組織code字段,萬一哪天組織表中的組織code有修改,不得不通過某種機制,通知我們同步修改評價表的組織code,不然就會出現數據不一致的問題。

很顯然,如果要這樣調整的話,業務流程上要改了,代碼改動有點大。

所以,還是先保持在接口中遠程調用吧。

這樣看來,可以優化的地方只能在:for循環中查詢數據。

第一次優化

由于需要在for循環中,每條記錄都要根據不同的條件,查詢出想要的數據。

由于業務系統調用這個接口時,沒有傳id,不好在where條件中用id in (...),這方式批量查詢數據。

其實,有一種辦法不用循環查詢,一條sql就能搞定需求:使用or關鍵字拼接,例如:

(org_code='001' and category_id=123 and business_id=111 and business_type=1) or (org_code='002' and category_id=123 and business_id=112 and business_type=2) or (org_code='003' and category_id=124 and business_id=117 and business_type=1)...

這種方式會導致sql語句會非常長,性能也會很差。

其實還有一種寫法:

where (a,b) in ((1,2),(1,3)...)

不過這種sql,如果一次性查詢的數據量太多的話,性能也不太好。

居然沒法改成批量查詢,就只能優化單條查詢sql的執行效率了。

首先從索引入手,因為改造成本最低。

第一次優化是優化索引。

評價表之前建立一個business_id字段的普通索引,但是從目前來看效率不太理想。

由于我果斷加了聯合索引:

alter table user_score add index  `un_org_category_business` (`org_code`,`category_id`,`business_id`,`business_type`) USING BTREE;

該聯合索引由:org_code、category_id、business_id和business_type四個字段組成。

經過這次優化,效果立竿見影。

批量評價查詢接口最大耗時,從最初的20s,縮短到了5s左右。

第二次優化

由于需要在for循環中,每條記錄都要根據不同的條件,查詢出想要的數據。

只在一個線程中查詢數據,顯然太慢。

那么,為何不能改成多線程調用?

第二次優化,查詢數據庫由單線程改成多線程。

但由于該接口是要將查詢出的所有數據,都返回回去的,所以要獲取查詢結果。

使用多線程調用,并且要獲取返回值,這種場景使用java8中的CompleteFuture非常合適。

代碼調整為:

CompletableFuture[] futureArray = dataList.stream()
.map(data -> CompletableFuture
.supplyAsync(() -> query(data), asyncExecutor)
.whenComplete((result, th) -> {
})).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futureArray).join();

CompleteFuture的本質是創建線程執行,為了避免產生太多的線程,所以使用線程池是非常有必要的。

優先推薦使用ThreadPoolExecutor類,我們自定義線程池。

具體代碼如下:

ExecutorService threadPool = new ThreadPoolExecutor(
8, //corePoolSize線程池中核心線程數
10, //maximumPoolSize 線程池中最大線程數
60, //線程池中線程的最大空閑時間,超過這個時間空閑線程將被回收
TimeUnit.SECONDS,//時間單位
new ArrayBlockingQueue(500), //隊列
new ThreadPoolExecutor.CallerRunsPolicy()); //拒絕策略

也可以使用ThreadPoolTaskExecutor類創建線程池:

@Configuration
public class ThreadPoolConfig {

/**
* 核心線程數量,默認1
*/
private int corePoolSize = 8;

/**
* 最大線程數量,默認Integer.MAX_VALUE;
*/
private int maxPoolSize = 10;

/**
* 空閑線程存活時間
*/
private int keepAliveSeconds = 60;

/**
* 線程阻塞隊列容量,默認Integer.MAX_VALUE
*/
private int queueCapacity = 1;

/**
* 是否允許核心線程超時
*/
private boolean allowCoreThreadTimeOut = false;

@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setAllowCoreThreadTimeOut(allowCoreThreadTimeOut);
// 設置拒絕策略,直接在execute方法的調用線程中運行被拒絕的任務
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 執行初始化
executor.initialize();
return executor;
}
}

經過這次優化,接口性能也提升了5倍。

從5s左右,縮短到1s左右。

但整體效果還不太理想。

第三次優化

經過前面的兩次優化,批量查詢評價接口性能有一些提升,但耗時還是大于1s。

出現這個問題的根本原因是:一次性查詢的數據太多。

那么,我們為什么不限制一下,每次查詢的記錄條數呢?

第三次優化,限制一次性查詢的記錄條數。其實之前也做了限制,不過最大是2000條記錄,從目前看效果不好。

限制該接口一次只能查200條記錄,如果超過200條則會報錯提示。

如果直接對該接口做限制,則可能會導致業務系統出現異常。

為了避免這種情況的發生,必須跟業務系統團隊一起討論一下優化方案。

主要有下面兩個方案:

1、前端做分頁

在結算單列表頁中,每個結算單默認只展示1個訂單,多余的分頁查詢。

這樣的話,如果按照每頁最大100條記錄計算的話,結算單和訂單最多一次只能查詢200條記錄。

這就需要業務系統的前端做分頁功能,同時后端接口要調整支持分頁查詢。

但目前現狀是前端沒有多余開發資源。

由于人手不足的原因,這套方案目前只能暫時擱置。

2、分批調用接口

業務系統后端之前是一次性調用評價查詢接口,現在改成分批調用。

比如:之前查詢500條記錄,業務系統只調用一次查詢接口。

現在改成業務系統每次只查100條記錄,分5批調用,總共也是查詢500條記錄。

這樣不是變慢了嗎?

答:如果那5批調用評價查詢接口的操作,是在for循環中單線程順序的,整體耗時當然可能會變慢。

但業務系統也可以改成多線程調用,只需最終匯總結果即可。

此時,有人可能會問題:在評價查詢接口的服務器多線程調用,跟在其他業務系統中多線程調用不是一回事?

還不如把批量評價查詢接口的服務器中,線程池的最大線程數調大一點?

顯然你忽略了一件事:線上應用一般不會被部署成單點。絕大多數情況下,為了避免因為服務器掛了,造成單點故障,基本會部署至少2個節點。這樣即使一個節點掛了,整個應用也能正常訪問。

當然也可能會出現這種情況:假如掛了一個節點,另外一個節點可能因為訪問的流量太大了,扛不住壓力,也可能因此掛掉。

換句話說,通過業務系統中的多線程調用接口,可以將訪問接口的流量負載均衡到不同的節點上。

他們也用8個線程,將數據分批,每批100條記錄,最后將結果匯總。

經過這次優化,接口性能再次提升了1倍。

從1s左右,縮短到小于500ms。

溫馨提醒一下,無論是在批量查詢評價接口查詢數據庫,還是在業務系統中調用批量查詢評價接口,使用多線程調用,都只是一個臨時方案,并不完美。

這樣做的原因主要是為了先快速解決問題,因為這種方案改動是最小的。

要從根本上解決問題,需要重新設計這一套功能,需要修改表結構,甚至可能需要修改業務流程。但由于牽涉到多條業務線,多個業務系統,只能排期慢慢做了。


責任編輯:張燕妮 來源: 蘇三說技術
相關推薦

2022-06-30 19:40:36

查詢接口索引優化

2022-09-19 08:41:02

數據查詢分離

2023-09-27 08:21:00

查詢分離數據API

2024-05-28 08:47:52

2024-08-30 09:31:36

2025-09-04 02:20:00

2022-07-05 10:50:31

數據庫查詢實戰

2025-11-11 04:00:00

2022-09-27 08:40:44

慢查詢MySQL定位優化

2025-10-27 02:11:00

2021-01-14 16:28:15

蠕蟲病毒刪除系統安全專家

2024-11-19 08:09:48

2025-02-20 09:27:46

2025-05-20 04:00:00

2025-06-05 02:25:00

2020-09-01 11:10:39

數據庫鏈接池HikariCP

2017-03-29 14:44:20

網絡性能優化

2022-05-17 09:02:30

前端性能優化

2009-04-20 08:51:50

MySQL查詢優化數據庫

2025-07-31 10:34:54

點贊
收藏

51CTO技術棧公眾號

这里只有精品电影| 久久久久一区二区三区四区| 欧美激情精品久久久久久久变态| 亚洲精品女人久久久| 亚洲伦理影院| 亚洲精品成人a在线观看| 久久综合九色99| 国产乱码一区二区| 在线精品亚洲| 日韩午夜在线视频| 99久久国产精| 粉嫩一区二区三区在线观看| 天天亚洲美女在线视频| 中文字幕一区二区三区四区五区六区 | 国产日韩欧美自拍| 91av在线免费视频| 欧美在线网址| 中文欧美在线视频| 亚洲永久无码7777kkk| 91成人短视频在线观看| 一本大道久久a久久综合婷婷| 看全色黄大色大片| 国产乱子伦三级在线播放| 看电视剧不卡顿的网站| 欧美中文在线观看国产| 国产真人真事毛片| 91精品蜜臀一区二区三区在线| 亚洲欧美制服综合另类| 亚洲麻豆一区二区三区| crdy在线观看欧美| 在线区一区二视频| 亚洲中文字幕无码专区| 丝袜美腿av在线| 国产精品久线观看视频| 日韩国产一区久久| 三级理论午夜在线观看| av中文字幕不卡| 粉嫩高清一区二区三区精品视频| 国产精品久久久久久久一区二区| 日韩综合在线视频| 97色在线视频观看| 国产在线视频二区| 欧美韩日精品| 欧美精品制服第一页| 国精产品一区一区| 欧美一级精品| 尤物yw午夜国产精品视频明星| 日韩精品卡通动漫网站| 免费萌白酱国产一区二区三区| 亚洲第一精品福利| 最新中文字幕日本| 亚洲精品在线播放| 亚洲精品一区二区三区99| 白丝校花扒腿让我c| 日韩精品成人在线观看| 欧美不卡在线视频| 国产女人18毛片水真多18| 国语一区二区三区| 亚洲国产97在线精品一区| 一级黄色片毛片| 国产美女撒尿一区二区| 日韩精品在线观看视频| 无遮挡aaaaa大片免费看| 免费av一区二区三区四区| 亚洲精品一二区| 亚洲国产日韩一区无码精品久久久| 亚洲三级网页| 中文字幕在线看视频国产欧美| 中文字幕第69页| 一区二区三区四区电影| 久久免费视频这里只有精品| 日韩精品一区二区不卡| 久久午夜电影| 成人免费淫片视频软件| 亚洲精品97久久中文字幕无码| 成人综合激情网| 久久久久久久久久久一区| 国产一区二区影视| 自拍av一区二区三区| 国产制服91一区二区三区制服| av老司机在线观看| 色就色 综合激情| 亚洲午夜精品一区| 东京久久高清| 一区二区三区高清国产| 国产福利视频网站| 国产欧美精品| 国产欧美日韩免费| 亚洲AV无码精品自拍| 久久色.com| 午夜啪啪福利视频| 在线观看v片| 69堂国产成人免费视频| 最近中文字幕无免费| 国产精品一线天粉嫩av| 伊人成人开心激情综合网| 日韩高清dvd碟片| 亚洲一区国产一区| 91精品在线播放| 亚洲人妻一区二区| 成人免费在线视频| 欧美日韩国产精品激情在线播放| a一区二区三区亚洲| 亚洲精品中文字幕女同| 黄色录像二级片| 久久av在线| 99久久精品免费看国产四区| 精品视频一二区| 伊人开心综合网| www.99av.com| 日本国产精品| 久久99精品久久久久久青青91| 69av视频在线观看| 99国产欧美另类久久久精品| 亚洲五码在线观看视频| 国产麻豆一区| 亚洲日本欧美中文幕| 国产真实乱偷精品视频| 狠狠v欧美v日韩v亚洲ⅴ| 欧美精品一区二区三区在线四季| 欧美xxxx少妇| 日韩丝袜美女视频| 日韩在线观看免| 日一区二区三区| 精品蜜桃一区二区三区| 少女频道在线观看免费播放电视剧| 欧美性一二三区| 精品夜夜澡人妻无码av| 极品中文字幕一区| av在线亚洲男人的天堂| 成人av福利| 欧美美女黄视频| 九九热久久免费视频| 久色成人在线| 欧美国产一二三区| 国产激情视频在线看| 亚洲成人激情在线观看| 免费无码毛片一区二区app| 狠狠久久亚洲欧美| gogogo免费高清日本写真| 欧美天堂一区二区| 色多多国产成人永久免费网站 | 欧美喷潮久久久xxxxx| 国产又粗又猛又爽又黄av| 久久av最新网址| 青青草成人激情在线| 澳门成人av网| 亚洲人成网7777777国产| 69视频免费看| 国产精品嫩草久久久久| 欧美第一页浮力影院| 91久久夜色精品国产按摩| 国产综合在线观看视频| 成人短视频在线| 精品乱码亚洲一区二区不卡| 国产精品成人国产乱| 不卡影院免费观看| 成人免费在线小视频| 国产精品手机在线播放| 国产精品揄拍一区二区| 超碰porn在线| 亚洲国产另类 国产精品国产免费| 日韩成人免费观看| 国产亚洲一区二区三区四区| 一级特黄性色生活片| 欧美电影免费观看高清| 亚洲一区二区中文字幕| 丁香花高清在线观看完整版| 日韩激情第一页| 国产精品51麻豆cm传媒| 亚洲色图视频网| 李丽珍裸体午夜理伦片| 天堂久久久久va久久久久| 亚洲欧洲国产精品久久| 欧美9999| 8x海外华人永久免费日韩内陆视频| 久久视频www| 欧美另类videos死尸| 久久久久久久黄色| 久久综合色鬼综合色| 日本人视频jizz页码69| 欧美久久一级| 鲁鲁狠狠狠7777一区二区| 久久精品xxxxx| 欧美黑人一级爽快片淫片高清| 日本五码在线| 欧美精品在线一区二区三区| 精品无码黑人又粗又大又长| 久久久久久久久蜜桃| 波多野结衣在线免费观看| 亚洲综合精品| 精品91一区二区三区| 欧美日韩一本| 91久热免费在线视频| 天堂√中文最新版在线| 久久综合色影院| 嫩草在线播放| 精品久久久久久最新网址| www.久久精品视频| 亚洲在线成人精品| 亚洲a∨无码无在线观看| 99久久精品国产一区| 亚洲第一成肉网| 欧美亚洲一区| 亚洲 欧美 综合 另类 中字| 日本成人小视频| 久久免费一区| 99国产精品免费网站| 国产美女直播视频一区| 电影网一区二区| 久久久亚洲成人| 黄色小网站在线观看| 伊人久久大香线蕉av一区二区| 成人av一区二区三区在线观看| 91成人免费网站| 日韩免费黄色片| 亚洲乱码中文字幕综合| 亚洲一二三四视频| 久久美女艺术照精彩视频福利播放 | 色播亚洲视频在线观看| 欧美亚洲大陆| 国产不卡一区二区在线观看| 日韩专区视频| 国产精品欧美一区二区三区奶水| 无码小电影在线观看网站免费| 色综合视频一区中文字幕| 麻豆视频在线| 色妞欧美日韩在线| av大片在线看| 国产一区二区三区精品久久久| 亚洲区小说区图片区| 亚洲精品一区二区三区影院| 免费观看黄色av| 日韩片之四级片| 国产麻豆一精品一男同| 911国产精品| 一区二区日韩视频| 欧美精品三级在线观看| 在线观看免费高清视频| 欧美日韩一区三区| 中文字幕资源网| 欧美日韩一区精品| 国产又黄又爽视频| 欧美一区二区精品| www.97av| 亚洲第一区在线| 五月色婷婷综合| 日韩大片在线观看视频| 欧美白人做受xxxx视频| 国产午夜精品美女视频明星a级| 日本a一级在线免费播放| 亚洲欧美在线磁力| 成人一区二区不卡免费| 中文精品99久久国产香蕉| 日本欧美在线视频免费观看| 久久中文字幕在线视频| 怡红院红怡院欧美aⅴ怡春院| 欧美巨猛xxxx猛交黑人97人| 丰满的护士2在线观看高清| 91精品国产高清自在线看超| 亚洲承认视频| 国产剧情久久久久久| 久久免费福利| 国偷自产av一区二区三区小尤奈| 久草成人资源| 一区二区三区av| 黑丝一区二区三区| 日韩欧美精品在线观看视频| 久久精品国产网站| 国产精品无码自拍| 久久婷婷综合激情| 欧美色视频一区二区三区在线观看| 一区二区成人在线观看| 久久久国产精品成人免费| 日韩欧美成人免费视频| 亚洲一区二区激情| 精品乱人伦小说| 国产精品视频二区三区| 欧美大奶子在线| 这里有精品可以观看| 国产日韩亚洲欧美| 麻豆精品av| 一区二区三区我不卡| 亚洲日本欧美| 中日韩av在线播放| a亚洲天堂av| www日韩在线| 欧美日韩激情视频| 国产免费叼嘿网站免费| 日韩电影中文字幕| 很黄的网站在线观看| 性色av一区二区三区免费| 精品久久在线| 精品无码久久久久久久动漫| 国产精品久久久久久麻豆一区软件 | 亚洲狠狠婷婷综合久久久| 国产精品激情电影| 亚洲欧美在线精品| 91女厕偷拍女厕偷拍高清| 波多野结衣久久久久| 欧美性极品xxxx做受| 成人福利小视频| 久久精品国产v日韩v亚洲| xx欧美xxx| 国产乱人伦精品一区二区| 无需播放器亚洲| 日韩网址在线观看| youjizz久久| 国产suv一区二区三区| 欧美系列在线观看| 水莓100在线视频| 欧美激情二区三区| 国产一区一区| 亚洲一区二区精品在线| 首页国产欧美日韩丝袜| a天堂视频在线观看| 亚洲精品午夜久久久| 一区二区三区免费在线视频| 亚洲日韩中文字幕| 日韩理论视频| 久久精品国产第一区二区三区最新章节 | 日韩精品导航| 免费一级淫片aaa片毛片a级| 国产真实乱偷精品视频免| 精品国产无码在线观看| 欧美日韩一区二区在线| 日本黄色免费视频| 久久全国免费视频| 成人爽a毛片免费啪啪红桃视频| 视频一区二区视频| 黄色资源网久久资源365| 午夜成人亚洲理伦片在线观看| 欧美色窝79yyyycom| 电影av一区| 国产精品黄视频| 欧美系列电影免费观看| 在线视频日韩一区| 国产欧美一区二区三区在线看蜜臀| 青青青国产在线 | 国产精品v欧美精品v日韩| 欧美~级网站不卡| www.偷拍.com| 亚洲综合成人在线视频| 高清毛片aaaaaaaaa片| 欧美精品videos性欧美| 国产精品巨作av| 欧美成人免费在线观看视频| 99精品黄色片免费大全| 国产又粗又猛又黄视频| 夜夜嗨av色综合久久久综合网| 成人av色网站| 中国人体摄影一区二区三区| 精品无人码麻豆乱码1区2区| 欧美色图亚洲视频| 亚洲成人黄色在线| 丝袜美腿一区| 亚洲一区二区三区色| 国产精品中文字幕欧美| 国产精选第一页| 亚洲精品午夜精品| 四虎国产精品免费久久| 青青视频免费在线观看| yourporn久久国产精品| 欧美特级黄色片| 粗暴蹂躏中文一区二区三区| 成人h动漫免费观看网站| 日韩精品视频久久| 国产精品毛片久久久久久| 国产成人麻豆精品午夜在线| 久久久久久中文| 精品国产1区| wwwxxxx在线观看| 欧美日韩色婷婷| 在线播放日本| 国产精品国产精品| 日韩电影免费在线看| 欧美特级一级片| 亚洲毛片在线观看| 亚洲精品aaa| aa在线免费观看| 亚洲日本成人在线观看| 亚洲欧美日本在线观看| 国产欧美最新羞羞视频在线观看| 欧美日一区二区在线观看 | 人妻精品一区二区三区| 国产精品青青在线观看爽香蕉| 欧美日韩mv| 精品一区二区三区蜜桃在线| 日韩精品一区二区三区蜜臀| 欧美性片在线观看| 日韩 欧美 视频| 国产精品久久久久三级| 天天摸天天干天天操| 成人国产在线视频| 欧美亚洲在线| 日产精品久久久久| 久久精品国产成人精品| 成人精品中文字幕| 亚洲一区二区三区四区五区六区 | 无码精品黑人一区二区三区|