【64期】MySQL 服務(wù)占用cpu 100%,如何排查問題? (MySQL面試第七彈)
一、引子
二、問題復(fù)現(xiàn)
三、問題排查
3.1 核心排查步驟
執(zhí)行
top命令:查看所有進(jìn)程占系統(tǒng)CPU的排序。極大可能排第一個(gè)的就是咱們的java進(jìn)程(COMMAND列)。PID那一列就是進(jìn)程號(hào)。執(zhí)行
top -Hp 進(jìn)程號(hào)命令:查看java進(jìn)程下的所有線程占CPU的情況。執(zhí)行
printf "%x\n 10命令 :后續(xù)查看線程堆棧信息展示的都是十六進(jìn)制,為了找到咱們的線程堆棧信息,咱們需要把線程號(hào)轉(zhuǎn)成16進(jìn)制。例如,printf "%x\n 10-》打印:a,那么在jstack中線程號(hào)就是0xa.執(zhí)行?
jstack 進(jìn)程號(hào) | grep 線程ID?查找某進(jìn)程下-》線程ID(jstack堆棧信息中的nid)=0xa的線程狀態(tài)。如果"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable,第一個(gè)雙引號(hào)圈起來的就是線程名,如果是“VM Thread”這就是虛擬機(jī)GC回收線程了執(zhí)行
jstat -gcutil 進(jìn)程號(hào) 統(tǒng)計(jì)間隔毫秒 統(tǒng)計(jì)次數(shù)(缺省代表一致統(tǒng)計(jì)),查看某進(jìn)程GC持續(xù)變化情況,如果發(fā)現(xiàn)返回中FGC很大且一直增大-》確認(rèn)Full GC! 也可以使用jmap -heap 進(jìn)程ID查看一下進(jìn)程的堆內(nèi)從是不是要溢出了,特別是老年代內(nèi)從使用情況一般是達(dá)到閾值(具體看垃圾回收器和啟動(dòng)時(shí)配置的閾值)就會(huì)進(jìn)程Full GC。執(zhí)行
jmap -dump:format=b,file=filename 進(jìn)程ID,導(dǎo)出某進(jìn)程下內(nèi)存heap輸出到文件中。可以通過eclipse的mat工具查看內(nèi)存中有哪些對(duì)象比較多。
3.2 原因分析
1.內(nèi)存消耗過大,導(dǎo)致Full GC次數(shù)過多
多個(gè)線程的CPU都超過了100%,通過jstack命令可以看到這些線程主要是垃圾回收線程-》上一節(jié)步驟2
通過jstat命令監(jiān)控GC情況,可以看到Full GC次數(shù)非常多,并且次數(shù)在不斷增加。--》上一節(jié)步驟5
生成大量的對(duì)象,導(dǎo)致內(nèi)存溢出-》執(zhí)行步驟6,查看具體內(nèi)存對(duì)象占用情況。
內(nèi)存占用不高,但是Full GC次數(shù)還是比較多,此時(shí)可能是代碼中手動(dòng)調(diào)用 System.gc()導(dǎo)致GC次數(shù)過多,這可以通過添加 -XX:+DisableExplicitGC來禁用JVM對(duì)顯示GC的響應(yīng)。
2.代碼中有大量消耗CPU的操作,導(dǎo)致CPU過高,系統(tǒng)運(yùn)行緩慢;
3.由于鎖使用不當(dāng),導(dǎo)致死鎖。
4.隨機(jī)出現(xiàn)大量線程訪問接口緩慢。
"http-nio-8080-exec-4"?#31?daemon?prio=5?os_prio=31?tid=0x00007fd08d0fa000?nid=0x6403?waiting?on?condition?[0x00007000033db000]
???java.lang.Thread.State:?TIMED_WAITING?(sleeping)-》期限等待
????at?java.lang.Thread.sleep(Native?Method)
????at?java.lang.Thread.sleep(Thread.java:340)
????at?java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
????at?com.*.user.controller.UserController.detail(UserController.java:18)-》業(yè)務(wù)代碼阻塞點(diǎn)
5.某個(gè)線程由于某種原因而進(jìn)入WAITING狀態(tài),此時(shí)該功能整體不可用,但是無法復(fù)現(xiàn);
"Thread-0"?#11?prio=5?os_prio=31?tid=0x00007f9de08c7000?nid=0x5603?waiting?on?condition?[0x0000700001f89000]???
java.lang.Thread.State:?WAITING?(parking)?->無期限等待
at?sun.misc.Unsafe.park(Native?Method)????
at?java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)????
at?com.*.SyncTask.lambda$main$0(SyncTask.java:8)-》業(yè)務(wù)代碼阻塞點(diǎn)
at?com.*.SyncTask$$Lambda$1/1791741888.run(Unknown?Source)????
at?java.lang.Thread.run(Thread.java:748)
四、總結(jié)
推薦閱讀:
【63期】談?wù)凪ySQL 索引,B+樹原理,以及建索引的幾大原則(MySQL面試第六彈)
【62期】解釋一下MySQL中內(nèi)連接,外連接等的區(qū)別(MySQL面試第五彈)
【61期】MySQL行鎖和表鎖的含義及區(qū)別(MySQL面試第四彈)
微信掃描二維碼,關(guān)注我的公眾號(hào)
朕已閱?

