Linux(2)---記錄一次線上服務 CPU 100%的排查過程


Linux(2)---記錄一次線上服務 CPU 100%的排查過程

當時產生CPU飆升接近100%的原因是因為項目中的websocket時時斷開又重連導致CPU飆升接近100% 。如何排查的呢 是通過日志輸出錯誤信息: 得知websocket時時重新
連接的信息,然后找到原因 解決了。
當然這里幸好能通過日志大致分析出原因 那么我就在思考如果日志沒有告訴任何信息 但線上CPU還是接近100%那么如何排查呢。所以學習了下排查過程。
通過查閱資料並實踐后,這里總結了兩種辦法。第一種博客滿天飛的方法 通過top命令 第二種非常好用 通過大牛寫的腳本排查

一、top命令排查

1、命令四部曲

(1)通過top命令,知道CPU最高的進程

top

(2)具體查看java中哪個線程一直在占用cpu時間(這里我的java進程號是: 8752)

 #java進程ID進行CPU占用排查(sort -rn 以數值的方式進行逆序排列)
 ps -mp 8752 -o THREAD,tid,time | sort -rn | more  

(3)根據2中查找到的CPU最高的排序中的結果,找出幾個占用cpu時間比較高的TID,將線程ID轉換為16進制

printf "%x\n" TID

(4)再使用jstack命名查詢是哪個線程

#8752是java進程ID,6669是第三步線程ID轉換的16進制
jstack 8752 |grep 6669 -A 30

2、案例

(1) top命令

(2)ps命令

(3)printf命令

(4)jstack命令


二、show-busy-java-threads.sh腳本

上面的 4 步雖然能夠排查問題,但總的還是還是太繁瑣耗時了,於是有大神寫了個腳本,在有問題的時候一鍵定位,能夠妙計找到問題。這個作者是一個叫淘寶的oldratlee 同學

1、腳本使用說明

怎么使用呢?可以看作者的GitHub地址中的文檔說明,而且里面也有相應腳本:Github

我們可以把這個git項目clone到Linux環境中(說明:目前這個腳本只支持linux環境)

git clone https://github.com/oldratlee/useful-scripts.git  #將下面下載到linux環境中。

這里也整理一些該腳本的常用命令

show-busy-java-threads.sh
# 從 所有的 Java進程中找出最消耗CPU的線程(缺省5個),打印出其線程棧。

show-busy-java-threads.sh -c <要顯示的線程棧數>

show-busy-java-threads.sh -c <要顯示的線程棧數> -p <指定的Java Process>
# -F選項:執行jstack命令時加上-F選項(強制jstack),一般情況不需要使用

show-busy-java-threads.sh -p <指定的Java Process> -F

show-busy-java-threads.sh -s <指定jstack命令的全路徑>
# 對於sudo方式的運行,JAVA_HOME環境變量不能傳遞給root,
# 而root用戶往往沒有配置JAVA_HOME且不方便配置,
# 顯式指定jstack命令的路徑就反而顯得更方便了

show-busy-java-threads.sh -a <輸出記錄到的文件>

show-busy-java-threads.sh -t <重復執行的次數> -i <重復執行的間隔秒數>
# 缺省執行一次;執行間隔缺省是3秒

##############################
# 注意:
##############################
# 如果Java進程的用戶 與 執行腳本的當前用戶 不同,則jstack不了這個Java進程。
# 為了能切換到Java進程的用戶,需要加sudo來執行,即可以解決:
sudo show-busy-java-threads.sh

2、案例說明

為了反應真實性,找了個能讓CPU飆升100%的代碼打包成jar在線上跑,這里采用定時任務讓它跑起來。

//java 正則表達式回溯造成 CPU 100%
@Service
public class GateTrigger {
   
    @Scheduled(fixedDelay = 1 * 1000)
    public void startSummary() {
        String[] patternMatch = {"([\\w\\s]+)+([+\\-/*])+([\\w\\s]+)",
                "([\\w\\s]+)+([+\\-/*])+([\\w\\s]+)+([+\\-/*])+([\\w\\s]+)"};
        List<String> patternList = new ArrayList<String>();

        patternList.add("Avg Volume Units product A + Volume Units product A");
        patternList.add("Avg Volume Units /  Volume Units product A");
        patternList.add("Avg retailer On Hand / Volume Units Plan / Store Count");
        patternList.add("Avg Hand Volume Units Plan Store Count");
        patternList.add("1 - Avg merchant Volume Units");
        patternList.add("Total retailer shipment Count");

        for (String s : patternList) {
            for (int i = 0; i < patternMatch.length; i++) {
                Pattern pattern = Pattern.compile(patternMatch[i]);

                Matcher matcher = pattern.matcher(s);
                System.out.println(s);
                //CPU飆升根源
                if (matcher.matches()) {

                    System.out.println("Passed");
                } else
                    System.out.println("Failed;");
            }
       }}
}

(1)top命令 發現CPU的確飆升了

(2)執行腳本

bash show-busy-java-threads.sh

(3)看后台運行結果


......

發現一下子就定位問題了,不得不說缺少很方便,快捷。

參考

1、Java死鎖排查和Java CPU 100% 排查的步驟整理

2、線上服務 CPU 100%?一鍵定位 so easy!




``` 如果一個人充滿快樂,正面的思想,那么好的人事物就會和他共鳴,而且被他吸引過來。同樣,一個人老帶悲傷,倒霉的事情也會跟過來。 ​ ——在自己心情低落的時候,告誡自己不要把負能量帶給別人。(大校10) ```


免責聲明!

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



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