日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

尊嘟假嘟?三行代码提升接口性能600倍

發(fā)布時間:2024/1/11 windows 34 coder
生活随笔 收集整理的這篇文章主要介紹了 尊嘟假嘟?三行代码提升接口性能600倍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、背景

??業(yè)務(wù)在群里反饋編輯結(jié)算單時有些賬單明細(xì)查不出來,但是新建結(jié)算單可以,我第一反應(yīng)是去測試環(huán)境試試有沒有該問題,結(jié)果發(fā)現(xiàn)沒任何問題!!!
??然后我登錄生產(chǎn)環(huán)境編輯業(yè)務(wù)反饋有問題的結(jié)算單,發(fā)現(xiàn)查詢接口直接504網(wǎng)關(guān)超時了,此時心里已經(jīng)猜到是代碼性能問題導(dǎo)致的,接來下就把重點放到排查接口超時的問題上了。

二、問題排查

遇到生產(chǎn)問題先查日志是基本操作,登錄阿里云的日志平臺,可以查到接口耗時竟然高達(dá)469245毫秒

這個結(jié)算單關(guān)聯(lián)的賬單數(shù)量也就800多條,所以可以肯定這個接口存在性能問題。

但是日志除了接口耗時,并沒有其他報錯信息或異常信息,看不出哪里導(dǎo)致了接口慢。

接口慢一般是由如下幾個原因?qū)е拢?/strong>

  1. 依賴的外部系統(tǒng)慢,比如同步調(diào)用外部系統(tǒng)的接口耗時比較久
  2. 處理的數(shù)據(jù)過多導(dǎo)致
  3. sql性能有問題,存在慢sql
  4. 有大循環(huán)存在循環(huán)處理的邏輯,如循環(huán)讀取exel并處理
  5. 網(wǎng)絡(luò)問題或者依賴的中間件比較慢
  6. 如果使用了鎖,也可能由于長時間獲取不到鎖導(dǎo)致接口超時

當(dāng)然也可以使用arthas的trace命令分析哪一塊比較耗時。

由于安裝arthas有點麻煩,就先猜測可能慢sql導(dǎo)致的,然后就登錄阿里云RDS查看了慢sql監(jiān)控日志。

好家伙一看嚇一跳,sql耗時竟然高達(dá)66秒,而且執(zhí)行次數(shù)還挺多!

我趕緊把sql語句放到數(shù)據(jù)庫用explain命令看下執(zhí)行計劃,分析這條sql為啥這么慢。

EXPLAIN SELECT DISTINCT(bill_code) FROM `t_bill_detail_2023_4` WHERE  
(settlement_order_code IS NULL OR settlement_order_code = 'JS23122600000001');

分析結(jié)果如下:

如果不知道explain結(jié)果每個字段的含義,可以看看這篇文章《長達(dá)1.7萬字的explain關(guān)鍵字指南!》。

可以看到掃描行數(shù)達(dá)到了250多萬行,ref已經(jīng)是最高效的const,但是看最后的Extra列
Using temporary 表明這個sql用到了臨時表,頓時心里清楚什么原因了。

因為sql有個去重關(guān)鍵字DISTINCT,所以mysql在需要建臨時表來完成查詢結(jié)果集的去重操作,如果結(jié)果集數(shù)據(jù)量比較小沒有超過buffer,就可以直接在內(nèi)存中去重,這種效率也是比較高的。

但是如果結(jié)果集數(shù)據(jù)量很大,buffer存不下,那就需要借助磁盤完成去重了,我們都知道操作磁盤相比內(nèi)存是非常慢的,時間差幾個數(shù)量級

雖然這個表里的settlement_order_code字段是有索引的,但是線上也有很多settlement_order_code為null的數(shù)據(jù),這就導(dǎo)致查出來的結(jié)果集非常大,然后又用到臨時表,所以sql耗時才這么久!

同時,這里也解釋了為什么測試環(huán)境沒有發(fā)現(xiàn)這個問題,因為測試環(huán)境的數(shù)據(jù)不多,直接在內(nèi)存就完成去重了。

三、問題解決

知道了問題原因就很好解決了,首先根據(jù)SQL和接口地址很快就找到出現(xiàn)問題的代碼是下圖紅框圈出來的地方

可以看到代碼前面有個判斷,只有當(dāng)isThreeOrderQuery=true時才會執(zhí)行這個查詢,判斷方法代碼如下

然后因為這是個編輯場景,前端會把當(dāng)前結(jié)算單號(usedSettlementOrderCode字段)傳給后端,所以這個方法就返回了true。

同理,拼接出來的sql就帶了條件(settlement_order_code IS NULL OR settlement_order_code = 'JS23122600000001')。

解決起來也很簡單,把isThreeOrderQuery()方法圈出來的代碼去掉就行了,這樣就不會執(zhí)行那個查詢,同時也不會影響原有的代碼邏輯,因為后面會根據(jù)篩選條件再查一次t_bill_detail表。

改代碼發(fā)布后,再編輯結(jié)算單,優(yōu)化后的效果如下圖:

只改了三行代碼,接口耗時就立馬從469245ms縮短到700ms,性能提升了600多倍

四、總結(jié)

感覺壓測環(huán)境還是有必要的,有些問題數(shù)據(jù)量小了或者請求并發(fā)不夠都沒法暴露出來,同時以后寫代碼可以提前把sql在數(shù)據(jù)庫explain下看看性能如何,畢竟能跑就行不是我們的追求??。

總結(jié)

以上是生活随笔為你收集整理的尊嘟假嘟?三行代码提升接口性能600倍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。