之前說到,我們的慢sql因為早期的程序員都很初級,因此,線上跑的慢sql滿天飛;雖然做了DB隔離,把慢sql的影響局限在各自的微服務內(nèi),但還是要去解決。
當時的環(huán)境是,我們的業(yè)務迭代的速度非常瘋狂,我們沒有余暇去優(yōu)化sql,甚至團隊有能力優(yōu)化的也沒有幾個,面對這個問題,我想到一個比較有趣的辦法,做慢sql排名。
排名之前,是要做監(jiān)控,我們通過druid收集sql的監(jiān)控信息,把他們放到表里做排序,排序的規(guī)則是,按照出現(xiàn)次數(shù) * RT時間來排;然后,我們只解決每天排名的TOP10,一年的時間,我們就幾乎沒有慢sql再出現(xiàn)了。

解決了慢sql的歷史問題,那新出現(xiàn)的問題,我們怎么快速解決呢?我相信大多數(shù)的公司都會有慢接口報警、慢sql報警的,只是這些報警一般不大會有人看。在我以前的公司,一般都是運維童鞋定期會拉出一個長長的列表,在全公司層面發(fā)出來,讓大伙去解決。
我們是怎么做的呢?答案是,日志接入釘釘。
通過釘釘?shù)募皶r通信和提醒效果,第一時間觸達給后端人員,再通過測試和后端共同的維護機制,保障每個慢sql都能被很及時的解決。

說到慢sql,有一個場景我要提一下,比如,突然某一個時段,我們發(fā)現(xiàn)接口出現(xiàn)了很高的RT延時,我們該如何排查呢?這里順便給出一下我的排查思路。
- 先看慢接口,通過慢接口來確定是后端的哪個應用。
- 再去查找后端的應用,查看是否用運行異常,一般來說就看看ECS上的mem、cpu、網(wǎng)卡是否有飆升,如果這些都正常,再檢查是不是FULL GC來引起的。
-
我的思路是,優(yōu)先看那個時段有沒有出現(xiàn)FULL GC,因為FULL GC的stw的時間很長,最長能超過1秒,一個健康的應用,一天內(nèi)也不會出現(xiàn)一次full gc;young gc,一般來說按頻率和時長來看,我的經(jīng)驗值是單次young gc最好不要超過100ms,1分鐘盡量不要超過5次young gc。我們的jdk的版本是8,截圖中你看到了元空間,因此它是G1。這里有些童鞋在問,JDK11已經(jīng)有ZGC了,為什么不用11呢?答案是成本,我們不確定目前的中間件中有多少和jdk11是不兼容的,我們的ARMS(鷹眼-全鏈路監(jiān)控)就不兼容,因此,盲目切換11帶來的收益,遠沒有損失大。
image.png -
這里出道題,如果linux上發(fā)現(xiàn)系統(tǒng)資源都被一個java進程占用了,通過什么步驟能查到呢?(要把大象放冰箱,總共分幾步呢?)
- top
- top -H
- printf "%x\n" 16進制異常線程號
- jstack 進程號|grep 16進制異常線程號 -A90
-
-
如果整體應用沒有問題,服務器各項指標沒有波動,那繼續(xù)排查數(shù)據(jù)庫,現(xiàn)在的阿里云的mysql(RDS)的監(jiān)控已經(jīng)做的非常好了,支持各種維度的性能監(jiān)控、全量sql查看、慢sql查看&分析等。我的思路是,先查找有問題的那個時間段,再將那個時間段的全量sql進行統(tǒng)計排序,一般用耗時比例來看看是哪個sql占用了最多的資源(不一定占用資源最多的就是有問題的),再通過掃描行數(shù),來看看是不是出現(xiàn)了不合理的sql。
image.png
image.png


