昨天線上容器突然cpu飆升,也是第一次排查這種問題所以記錄一下~
前言
首先問題是這樣的,周五正在寫文檔,突然收到了線上報(bào)警,發(fā)現(xiàn)cpu占用達(dá)到了90多,上平臺(tái)監(jiān)控系統(tǒng)查看容器,在jvm監(jiān)控中發(fā)現(xiàn)有一個(gè)pod在兩個(gè)小時(shí)內(nèi)產(chǎn)生了61次youngGc一次fullGc,這個(gè)問題特別嚴(yán)重且少見,由于我之前也沒有排查過此類問題,所以也是百度,但整個(gè)過程也有一些自己的思考,所以跟大家分享一下~
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
- 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
- 視頻教程:https://doc.iocoder.cn/video/
當(dāng)時(shí)場景
我先給大家看一下一副正常的gc曲線監(jiān)控(為保密性,我自己按照平臺(tái)監(jiān)控畫了出來):
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
正常的jvm監(jiān)控曲線圖

產(chǎn)生問題的jvm監(jiān)控曲線圖

可以看的出來,正常情況下該系統(tǒng)很少gc(具體看業(yè)務(wù)系統(tǒng)使用情況、jvm內(nèi)存分配),但是在圖二中出現(xiàn)了大量異常的gc情況甚至觸發(fā)了fullGc,所以我當(dāng)時(shí)立馬進(jìn)行了分析。
具體分析
首先異常gc的情況只出現(xiàn)在一個(gè)pod上(系統(tǒng)有多個(gè)pod),在監(jiān)控系統(tǒng)找到對應(yīng)的pod,進(jìn)入pod內(nèi)部查看問題原因,排查問題一定要冷靜
- 進(jìn)入pod之后,輸入top查看各linux進(jìn)程對系統(tǒng)資源的使用情況(因我這是事后補(bǔ)稿,資源使用不高,大家看步驟即可)

- 分析資源使用情況在當(dāng)時(shí)的情況下

當(dāng)時(shí)我的pid為1的進(jìn)程cpu上到了130(多核)那我認(rèn)定就是java應(yīng)用出問題了,control+c退出繼續(xù)往下走
- 輸入top -H -p pid 通過此命令可以查看實(shí)際占用CPU最高的的線程的id,pid為剛才資源使用高的pid號(hào)

- 出現(xiàn)具體線程的資源使用情況,表格里的pid代表線程的id,我們稱他為tid

- 我記得當(dāng)時(shí)的tip為746(上述圖片只是我給大家重復(fù)步驟),使用命令printf "%x " 746,將線程tid轉(zhuǎn)換為16進(jìn)制

因?yàn)槲覀兙€程id號(hào)在堆棧里是16進(jìn)制的所以需要做一個(gè)進(jìn)制轉(zhuǎn)換
- 輸入jstack pid | grep 2ea >gc.stack
jstackpid|grep2ea>gc.stack

解釋一下,jstack是jdk給提供的監(jiān)控調(diào)優(yōu)小工具之一,jstack會(huì)生成JVM當(dāng)前時(shí)刻的線程快照,然后我們可以通過它查看某個(gè)Java進(jìn)程內(nèi)的線程堆棧信息,之后我們把堆棧信息通過管道收集2ea線程的信息,然后將信息生成為gc.stack文件,我隨便起的,隨意
- 當(dāng)時(shí)我先cat gc.stack 發(fā)現(xiàn)數(shù)據(jù)有點(diǎn)多在容器里看不方便,于是我下載到本地瀏覽,因?yàn)楣緦Ω鱾€(gè)機(jī)器的訪問做了限制,我只能用跳板機(jī)先找到一臺(tái)沒用的機(jī)器a,把文件下載到a然后我再把a(bǔ)里的文件下載到本地(本地訪問跳板機(jī)OK),先輸入python -m SimpleHTTPServer 8080,linux自帶python,這個(gè)是開啟一個(gè)簡單http服務(wù)供外界訪問

然后登錄跳板機(jī),使用curl下載curl -o http://ip地址/gcInfo.stack
為方便演示,我在圖中把ip換了一個(gè)假的

之后用同樣的方法從本地下載跳板機(jī)就可以了,記得關(guān)閉python開啟的建議服務(wù)嗷
- 把文件下載到了本地,打開查看編輯器搜索2ea,找到nid為2ea的堆棧信息

之后找到對應(yīng)的impl根據(jù)行數(shù)分析程序
- 發(fā)現(xiàn)是在文件異步導(dǎo)出excel的時(shí)候,導(dǎo)出接口使用了公共列表查詢接口,列表接口查詢數(shù)據(jù)最多為分頁200一批,而導(dǎo)出數(shù)據(jù)量每個(gè)人的權(quán)限幾萬到十幾萬不等

并且該判斷方法使用了嵌套循環(huán)里判斷,且結(jié)合業(yè)務(wù)很容易 get 不到 value,Java 下的new ArrayList 就是返回一個(gè) List 集合(好像不用說這么細(xì) (;一_一 ),在整個(gè)方法結(jié)束之前,產(chǎn)生的 lists生命周期還在所以發(fā)生多次gc觸發(fā)重啟之后還影響到了別的pod。然后對代碼進(jìn)行了fix,緊急上線,問題解決~
結(jié)束語
遇到生產(chǎn)問題,大家不要害怕,遇到問題先保證服務(wù)是否可用,然后通過有限的信息層層解析,找出最終的問題。如果你會(huì) arthas,排查起來會(huì)更輕松!
-
cpu
+關(guān)注
關(guān)注
68文章
11090瀏覽量
217311 -
編輯器
+關(guān)注
關(guān)注
1文章
823瀏覽量
32088 -
進(jìn)程
+關(guān)注
關(guān)注
0文章
207瀏覽量
14297
原文標(biāo)題:new ArrayList 不當(dāng)導(dǎo)致 CPU 飆升。。
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
OpenHarmony語言基礎(chǔ)類庫【@ohos.util.ArrayList (線性容器ArrayList)】

存儲(chǔ)示波器觸發(fā)電平設(shè)置不當(dāng)會(huì)導(dǎo)致什么后果?
為什么f_mount后CPU使用率飆升10%?
如何解決STM32串口溢出錯(cuò)誤Overrun使用不當(dāng)導(dǎo)致的串口死機(jī)?
FlexSPI復(fù)位方式不當(dāng)會(huì)導(dǎo)致i.MXRT系列下OTFAD加密啟動(dòng)失敗怎么解決?
【學(xué)習(xí)打卡】OpenHarmony的ArrayList介紹
OpenHarmony應(yīng)用示例:線性容器 ArrayList
PCB Layout不當(dāng)引起CPU工作不穩(wěn)定的解決方法
螺桿支撐座安裝不當(dāng)會(huì)導(dǎo)致哪些問題發(fā)生?

JDK中java.util.ArrayList 類的介紹

ArrayList入門實(shí)踐

cpu溫度太高怎么解決?cpu溫度高的原因?
鴻蒙語言基礎(chǔ)類庫:ohos.util.ArrayList 線性容器ArrayList

評論