java 服務定期卡頓、卡死,服務在運行沒掛,日志瘋狂打印,接口不能用


生成環境同事反映每到早上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等

感謝閱讀!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM