記一次CPU突然飆公升到 100 問題排查

2021-09-29 14:50:40 字數 1699 閱讀 6904

線上 cpu 飈高問題該如何定位問題呢?

是因為執行緒太多,導致上下文切換?

還是因為應用****現了死迴圈?

還是gc頻繁導致 cpu 突然飆公升?

該如何入手呢?

首先要知道那些情況會導致 cpu 的突然飆公升:

頻繁gc,訪問量高時,有可能造成頻繁的gc、甚至fgc。當呼叫量大時,記憶體分配過快,就會造成gc執行緒不停的執行,導致cpu飆高

序列化與反序列化,例如應用**執行xml解析時,呼叫量增大的情況下,可能導致了cpu被打滿

加密、解密

正規表示式校驗(正則匹配回溯問題)

執行緒上下文切換、當啟動了很多執行緒,而這些執行緒都處於不斷的阻塞狀態(鎖等待、io等待等)和執行狀態的變化過程中。當鎖競爭激烈時,很容易出現這種情況

某些執行緒在做無阻塞的運算,簡單的例子while(true)中不停的做運算,沒有任何阻塞。寫程式時,如果需要做很久的計算,可以適當將程式sleep下

實際案例

在一次生產切庫時,暫停了 kafka 的消費,大概切了8個小時,導致 kafka 內堆積了大量的資料(ps:一些統計資料),當重新啟動消費的時候,cpu 迅速打滿。

排查問題:

因為在消費kafka時,使用了多執行緒進行消費,並且使用了 executor 框架提供的executors.newfixedthreadpool(50),設定了 50,導致產生大量的執行緒在做上下文切換

vmstat可以檢視執行緒上下文切換的頻率

參考文章:linux vmstat命令詳解

將執行緒數降為6,cpu 恢復正常。

這是在明確知道可能出現cpu飆公升出現的情況。

大多數情況下是不會明確知道問題出在**的?那該如何進行排查呢?

使用 top 命令查詢 cpu 佔比最高的執行緒

2. 根據前面的 pid,使用 top -h -p pid 檢視該程序的執行緒資訊,檢視是那個執行緒耗費 cpu

top -h -p pid
找到占用 cpu 最高的執行緒的 pid,例如 88

使用 printf 「%x\n」 88,列印該執行緒的 16 進製數值

print "%x\n" 88

58

使用 jstack 命令將程序 pid 的堆疊資訊倒出來

jstack pid > pid.log
開啟 pid.log, 查詢 執行緒 nid 為 58 的執行緒即為 cpu 最高占用的執行緒。

tips

現在大部分應用都是使用docker執行,在查詢的過程中,如何對應docker內的程序pid與宿主機的程序pid

使用 docker top name

如上 pid 即為該 docker 映象在宿主機中的pid

記一次mongodb CPU飆公升100 的解決

問題的發現過程是這樣的,一些硬體裝置上傳的實時裝置資訊客戶端不能展現,於是查詢日誌,發現資料時間延遲非常嚴重,後台邏輯把這些資料當作過期資料扔掉了,所以沒有進入實時資料的服務 此服務是單獨部署的 於是開始查問題,難道原始資料就是過期的?鑑於北京的霧霾天可能對北斗 ps 我們主要是裝置的北斗位置資料 ...

記一次解決MYSQL占用CPU100 的問題

有張表50w條資料,今天寫了個job每隔10秒對其進行分組查詢並獲取每組的第一條資料。select select kvarh total from e monitorhours where mobusid a.mobusid order by id desc limit 1 askvarh tota...

記一次專案cpu100 情況解決過程

下午14 29分,運維突然告知,某專案cpu100 趕緊找到運維開始排查問題 一 通過top命令排查出占用執行緒,發現占用cpu的執行緒是gc程式 見 二 通過jstat命令檢視記憶體狀態,發現full gc達到150多次。此時仍然無法定位問題。三 通過檢視異常時間段nginx日誌,發現有個介面傳的...