生成環境同事反映每到早上7-8點,高峰期服務卡死,日志瘋狂打印,接口不能用,持續半個小時到一個小時,
那就懟唄,早上6點多趕到公司在服務卡頓時排查:
1 首先top看cpu飆高80以上甚至100%,其中mysql進程高達1000%,java300%。好吧,不用說肯定mysql或者sql有問題,看mysql配置好像沒啥問題。
那就是sql了,把mysql-slow.log慢sql日志拿出來,一條一條sql全部優化一遍,加索引,改sql各種操作搞了一上午加半個下午。
此時服務器過來7-8點的卡頓時間段了,查詢業務性能確實提高,mysql cpu也降下來了穩定在50%左右,整個服務器cpu也下來了,5-20%的波動。當時就想這下應該是沒問題了。
mysql優化比完,但是過了高峰期看不出來7-8點效果,只能等第二天了。
2 第二天早上一看,我去,又卡死,怎么辦,再看cpu,也沒飆高到之前,最高70%,設置的cpu過80%告警都沒觸發,怎么回事?
繼續查,
接口訪問量過大?調出系統日志,nginx日志access.log統計一波,並發量不大啊
網絡問題?ping服務器發現沒有丟包,nethogs測網也正常,好,排除
io讀寫問題?iostat -x 1 io有波動,但也沒發現io等待時間過長的異常現象,好吧,也不是這個問題,不過由於我們的內存是足夠的100g呢,還是優化了一下/sys/block/sda/queue/nr_requests,128改到512,
內存問題?free -h 發現buff/cache超大,used才機器的一半內存,剩下的這么都在buff/cache 於是 echo 1 > /proc/sys/vm/drop_caches。
嗯,這樣應該沒啥問題了
3 第三天發現又是難受的一天,還是卡得一批,這個要干上了啊
只能上終極武器jvm了,
1 使用top命令定位異常進程。可以看見12836的CPU和內存占用率都非常高
2. 使用top -H -p 2370進程號查看異常線程
3 獲取線程id的16進制,printf "%x\n" 50342線程id
4 jstack 進程號 | grep 線程id16進制
jstack 11800 | grep `printf "%x\n" 12608` -A 10
jstack -l 11800
發現DubboServerHandler WAITING這個不是dubbo嘛,哦,一看原來是dubbo線程池500不夠用,於是改成1000,dispatcher 還是默認的?改message
<dubbo:protocol name="dubbo" port="31880" dispatcher="message" threads="1000" />
還有gc? 原來啟動腳本啥參數也沒給,於是改成:
java -XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200 -jar xxx
4 第四天一看 我靠,系統空閑是性能提升了,但是還有卡頓,於是想到了定時任務,查看項目所有定時任務,統計執行時間,對調接口響應時間長的定時任務做異步處理,調用頻繁的查詢接口使用緩存直接返回結果,大功告成!
總結:性能問題
1 cpu、內存、io進程排查,使用 top、iotop、nethogs、iostat -x 1等命令
2 慢sql優化,加索引,sql邏輯
3 接口響應慢的,緩存
4 執行時間長的定時任務,異步
5 對3、4中的業務邏輯排查是否存在循環查庫操作等
5 中間件(dubbo、redis、mysql等)性能參數優化,線程池大小等
6 jvm優化:jstack,gc等
感謝閱讀!