1. 程式人生 > >CPU負載120%

CPU負載120%

CPU負載120%


概述

  • 背景:生產環境服務響應緩慢,出現RPC介面超時
  • 排查:
    • 服務雙機部署,登入兩臺日誌機器,登入兩臺部署機器
    • 檢視部署機器服務負載,
      • top 檢視,同一臺機器上部署三個服務
      • 其中A服務,CPU 120%
      • 檢視剛出現 CPU 負載過高的時間,運維提供監控日誌顯示上午,檢視日誌,這期間發生的疑似操作
      • 定位問題,近期優化的一個批量初始化資料到快取中的功能被觸發了多次,且該功能為了快速響應,建立執行緒池,核心執行緒數10,最大執行緒數20,使用者進行了多次點選,每一次的資料請求量都很大,上一次操作沒有完成,下一次的請求即開始了

堆疊資訊1

  • 檢視負載高的程序
    • 進入部署伺服器
    • top , 按 P ,記錄CPU負載高的程序編號
  • 檢視負載高的程序
    • top -Ph pid 程序編號,按P ,記錄CPU負載高的執行緒編號
  • 執行緒編號轉為十六進位制,通過windows提供的科學計算器
  • 檢視堆疊資訊
    • jstack pid | grep “0xtid”

異常資訊

   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000073e4aa000> (a java.util.concurrent.SynchronousQueue$TransferStack)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
        at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
        at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)

private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(10, 20,
            300, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1000),
            new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    return t;
                }
            }, new ThreadPoolExecutor.CallerRunsPolicy());

根據堆疊資訊配置原始碼跟蹤問題原因定位於
伺服器CPU數量 2 個,A服務中存在不同的多個執行緒池,功能執行過程中交叉多個執行緒池的執行,每個執行緒在規定的時間內都沒有得到反饋,每個執行緒都在執行SQL查詢,沒有得到資料響應,執行緒掛起;不斷建立新的執行緒執行掛起的任務,發生資源爭搶,導致CPU負載過高


異常反思

  • 執行緒池使用要根據伺服器效能合理設定,建立數量過多會導致CPU負載過高

  1. 記錄一次cpu 100%線上問題排查 ↩︎