<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【64期】MySQL 服務(wù)占用cpu 100%,如何排查問題? (MySQL面試第七彈)

          共 3011字,需瀏覽 7分鐘

           ·

          2020-10-21 16:00

          程序員的成長之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?
          關(guān)注


          閱讀本文大概需要 4 分鐘。
          來自:cnblogs.com/dennyzhangdd/p/11585971.html

          一、引子

          對(duì)于互聯(lián)網(wǎng)公司,線上CPU飆升的問題很常見(例如某個(gè)活動(dòng)開始,流量突然飆升時(shí)),按照本文的步驟排查,基本1分鐘即可搞定!特此整理排查方法一篇,供大家參考討論提高。

          二、問題復(fù)現(xiàn)

          線上系統(tǒng)突然運(yùn)行緩慢,CPU飆升,甚至到100%,以及Full GC次數(shù)過多,接著就是各種報(bào)警:例如接口超時(shí)報(bào)警等。此時(shí)急需快速線上排查問題。

          三、問題排查

          不管什么問題,既然是CPU飆升,肯定是查一下耗CPU的線程,然后看看GC。

          3.1 核心排查步驟

          1. 執(zhí)行top命令:查看所有進(jìn)程占系統(tǒng)CPU的排序。極大可能排第一個(gè)的就是咱們的java進(jìn)程(COMMAND列)。PID那一列就是進(jìn)程號(hào)。

          2. 執(zhí)行top -Hp 進(jìn)程號(hào)命令:查看java進(jìn)程下的所有線程占CPU的情況。

          3. 執(zhí)行printf "%x\n 10命令 :后續(xù)查看線程堆棧信息展示的都是十六進(jìn)制,為了找到咱們的線程堆棧信息,咱們需要把線程號(hào)轉(zhuǎn)成16進(jìn)制。例如,printf "%x\n 10-》打印:a,那么在jstack中線程號(hào)就是0xa.

          4. 執(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回收線程了

          5. 執(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。

          6. 執(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ù)過多

          執(zhí)行步驟1-5:
          • 多個(gè)線程的CPU都超過了100%,通過jstack命令可以看到這些線程主要是垃圾回收線程-》上一節(jié)步驟2

          • 通過jstat命令監(jiān)控GC情況,可以看到Full GC次數(shù)非常多,并且次數(shù)在不斷增加。--》上一節(jié)步驟5

          確定是Full GC,接下來找到具體原因:
          • 生成大量的對(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)行緩慢;

          執(zhí)行步驟1-4:在步驟4jstack,可直接定位到代碼行。例如某些復(fù)雜算法,甚至算法BUG,無限循環(huán)遞歸等等。

          3.由于鎖使用不當(dāng),導(dǎo)致死鎖。

          執(zhí)行步驟1-4:如果有死鎖,會(huì)直接提示。關(guān)鍵字:deadlock.步驟四,會(huì)打印出業(yè)務(wù)死鎖的位置。
          造成死鎖的原因:最典型的就是2個(gè)線程互相等待對(duì)方持有的鎖。

          4.隨機(jī)出現(xiàn)大量線程訪問接口緩慢。

          代碼某個(gè)位置有阻塞性的操作,導(dǎo)致該功能調(diào)用整體比較耗時(shí),但出現(xiàn)是比較隨機(jī)的;平時(shí)消耗的CPU不多,而且占用的內(nèi)存也不高。
          思路:
          首先找到該接口,通過壓測工具不斷加大訪問力度,大量線程將阻塞于該阻塞點(diǎn)。
          執(zhí)行步驟1-4:
          "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)
          如上,找到業(yè)務(wù)代碼阻塞點(diǎn),這里業(yè)務(wù)代碼使用了TimeUnit.sleep()方法,使線程進(jìn)入了TIMED_WAITING(期限等待)狀態(tài)。

          5.某個(gè)線程由于某種原因而進(jìn)入WAITING狀態(tài),此時(shí)該功能整體不可用,但是無法復(fù)現(xiàn);

          執(zhí)行步驟1-4:jstack多查詢幾次,每次間隔30秒,對(duì)比一直停留在parking 導(dǎo)致的WAITING狀態(tài)的線程。
          例如CountDownLatch倒計(jì)時(shí)器,使得相關(guān)線程等待->AQS->LockSupport.park()。
          "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é)

          按照3.1節(jié)的6個(gè)步驟走下來,基本都能找到問題所在。

          推薦閱讀:

          【63期】談?wù)凪ySQL 索引,B+樹原理,以及建索引的幾大原則(MySQL面試第六彈)

          【62期】解釋一下MySQL中內(nèi)連接,外連接等的區(qū)別(MySQL面試第五彈)

          【61期】MySQL行鎖和表鎖的含義及區(qū)別(MySQL面試第四彈)

          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「2048」,即可免費(fèi)獲取!!

          微信掃描二維碼,關(guān)注我的公眾號(hào)

          朕已閱?

          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成年人观看黄色视频 | 青青草青娱乐在线 | 亚洲国产精品成人综合色在线婷婷 | 水蜜桃网站 | 日本网站在线 |