線上docker服務(wù)cpu100%的處理經(jīng)歷

前兩天上線一個(gè)springboot服務(wù)(docker容器部署),服務(wù)啟動成功后,cpu負(fù)載瞬間上來直接100%。這樣的表現(xiàn)顯然是程序某個(gè)地方有問題。

1.第一反應(yīng)就是某個(gè)地方的邏輯形成了死循環(huán)。當(dāng)時(shí)通過shell命令

top

顯示


image-20201122203110060.png

可以得到的信息是pid是340,但是有一個(gè)疑問就是無法確定對應(yīng)的是哪個(gè)docker容器啟動的服務(wù)。

2.通過docker命令

docker stats

打印出每一個(gè)容器對應(yīng)的指標(biāo)參數(shù)。類似下面這種:
image-20201122210429567.png

那么通過以上兩個(gè)命令,就可以定位到底是哪個(gè)docker容器所承載的服務(wù)導(dǎo)致了cpu負(fù)載100%了。

既然已經(jīng)定位到了具體哪個(gè)服務(wù)導(dǎo)致的問題,那么下一步就要定位具體是哪個(gè)線程導(dǎo)致的問題?

3.通過shell命令打印進(jìn)程下所有線程的占用情況

top -H -p340

其中340就是第一步獲得的pid--->340

類似下面這種:
image-20201122211133339.png

查看cpu那一列,找到異常數(shù)據(jù)為100%的那一行,并記錄。

4.通過docker命令

docker exec -it {容器id} /bin/bash

進(jìn)入容器內(nèi)部。因?yàn)槭莟omcat容器,也就意味著安裝了JDK,那么可以使用jvm命令。

通過

jps

查看容器內(nèi)正在運(yùn)行的java服務(wù)。一般是只有一個(gè)服務(wù):
image-20201122212622415.png

那么咱們就可以直接通過以下命令打印線程堆棧

jstack -l 1 > pid.dump

1就是指的當(dāng)前運(yùn)行java服務(wù)的pid。

5.把以上pid.dump下載到本地,通過文本工具打開,結(jié)合【第三步】獲取的信息,結(jié)果定位到具體的線程堆棧:
image-20201122213226437.png

(實(shí)際上【第三步】可以明確是“pool-4-thread-3”這個(gè)線程導(dǎo)致cpu負(fù)載100%)

看以上截圖可知,問題出在TagHeartbeatCheckThread這個(gè)類的第55行。

6.根據(jù)提示,查看代碼:
image-20201122213651686.png

RfidDataCache這個(gè)是一個(gè)本地緩存,如果本地緩存為空,那么便會導(dǎo)致死循環(huán)。問題定位已經(jīng)完成。

7.根據(jù)上面一系列的操作及問題定位,已經(jīng)可以定位到問題產(chǎn)生的具體原因。想要解決這個(gè)問題,可以在判斷本地緩存為空的時(shí)候,讓線程睡眠2秒,降低cpu的負(fù)載;或者使用阻塞隊(duì)列的方式,讓線程等待直至本地緩存數(shù)據(jù)不為空。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容