線上 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日誌,發現有個介面傳的...