性能優化 ---- 如何排查線上性能問題

零. 概述

又到了一年一度某電商帝國雙十一大促備戰階段,今年我負責穩定性這塊,系統壓測找出性能瓶頸就是其中之一的工作。在壓測某個系統 A,線上集羣發現 CPU 使用率 50%,8C-16G-200G 的容器 load 達到 13 左右,嚇得立刻下掉了壓測流量。然後在預發環境單機壓測尋找性能瓶頸,廢話不多說,下面開始分析步驟。

 

一. 性能問題排查

壓測預發環境 單機 8C-16G-200G ,壓測目標 1800 QPS。

觀察:GC 次數/時間可控,數據庫RT維持在5ms以內,連接數使用正常2000+,只有 CPU 一項非常異常,使用率 90%,超過水位值 60%,load1 達到 45

壓測中進行了一次 java dump,觀察線程情況,發現了 TIMED_WAITING 佔了 80%,那麼說明這可能是他們都在等一個搶手的資源,也可能是正常的,他們是需要等待某個時機才能繼續做。

"Keep-Alive-Timer" #1159 daemon prio=8 os_prio=0 tid=0x00007fd9dc014000 nid=0x7853 sleeping[0x00007fd99abfb000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep0(Native Method)
    at java.lang.Thread.sleep(Thread.java:398)
    at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:172)
    at java.lang.Thread.run(Thread.java:882)

   Locked ownable synchronizers:
    - None

從堆棧沒看出到底卡在哪個地方了?知道是線程卡住了,我們可以藉助一下阿里巴巴開源的 Arthas 來協助排查,使用 Thread -b 可以打印出線程被卡在哪裏

thread -b
"http-bio-8080-exec-4" Id=27 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at org.apache.log4j...
    -  locked java.lang.Object@725be470 <---- but blocks 66 other threads!
    

可以看出來我們是被日誌打印卡住了,我們知道 log4j、logback 默認的日誌打印都是同步的,且要是打印的是 debug或者info 級別會打印非常多日誌,非常消耗系統cpu及線程資源。知道問題原因,那麼問題就好解決了,日誌改成異步打印,線上系統只打印 ERROR 或者 WARN。改造之後壓測 QPS 立刻就能壓到目標值 1800,沒改造前最多單機只能到 980。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章