線上Spring CPU 高負載解決思路詳解
引言
背景: 在某一天,運營同事突然發(fā)現(xiàn)運營看板好幾天沒有更新數(shù)據(jù)了, 然后找了過來?!
這里看似拋出了一個問題 ?
但細想一下, 同時暴露了我們對于線上服務(wù)的監(jiān)控未完全覆蓋到!!! 這是致命的!!!
當然, 這篇文章先不討論監(jiān)控的問題, 后面會推出完善的監(jiān)控方案
定位問題
問題拋過來了, 那么我們第一步要怎樣做呢?
拿到問題的第一步, 先理解題意, 這里有幾個關(guān)鍵的信息點
第一 : 好幾天, 具體哪一天, 這個后面確認了一個具體的時間點
第二 : 運營看板, 這是重點, 是我們切入問題的關(guān)鍵
好了, 有了這兩個關(guān)鍵的信息, 我們接下來就開始定位問題代碼了
- 從功能出發(fā), 定位到未更新的表
- 通過表來定位到更新數(shù)據(jù)的代碼
通過上面兩步找到了問題代碼是某個定時任務(wù)
日志搜索
這時按照肌肉記憶, 先是看了代碼有沒有關(guān)鍵點的日志輸出, 發(fā)現(xiàn)代碼開始和結(jié)束都有打印日志的操作
順藤摸瓜,先登錄到服務(wù)器端, grep一波關(guān)鍵的日志
發(fā)現(xiàn)當天的 info.log 沒有打印到日志, 這就很奇怪了, 因為這個定時任務(wù)的 cron 是每天凌晨1點開始
然后就查了前一天的日志, 發(fā)現(xiàn)有打印到開始的日志, 但是沒有打印結(jié)束的日志
然后再去找看有沒有異常的日志, 發(fā)現(xiàn)并沒有
監(jiān)控看板
從日志看出了一點不對勁的味道, 但還沒有足夠的線索定位到具體的問題
這時去查看容器的資源情況

這里觀察的是, 在兩臺容器中, 有一臺容器的 cpu 吃得很緊
另外一臺卻是風平浪靜
從這里可以定位到大概的問題了: CPU負載高
那為什么會造成 CPU 跑那么高呢 ?
ThreadDump
當然有很多方案可以定位 CPU 的瓶頸問題,像使用火焰圖定位(下一篇會使用到)
但從上面的蛛絲馬跡里可以大體定位到是具體的定時任務(wù)引起的
這時 threaddump, 并分析了一波線程的運行情況

從整體的報告可以看出有阻塞的線程兩個, 同時有百分之四十是在超時等待
再看看具體被阻塞的線程

看起來是數(shù)據(jù)庫查詢阻塞
看具體的業(yè)務(wù)代碼

分析一下這條 SQL 的變量
入?yún)⒅挥幸粋€就是 classIds 數(shù)組:
- 數(shù)量很小
- 數(shù)量很大
- 數(shù)量為 0
數(shù)組的分布情況可以為上面幾種
套進去
- 數(shù)量很小, 查詢應(yīng)該很快
- 數(shù)量很大, 查詢應(yīng)該會相對慢一點
- 數(shù)量為 0 呢, if 標簽, classIds 數(shù)量為 0, 不會 拼接下面的 sql, 也就是會查全表
優(yōu)化
定位到具體的代碼了, 那就是要出優(yōu)化方案了
做法就是當 classIds 的大小為 0 的時候, 不要掃描全表

這里添加 otherwise 分支, classIds 大小為 0 是 and false
重新部署再觀察線上情況, CPU 降了下來

事后反思
為什么會這么久才發(fā)現(xiàn)問題? 而且依賴于業(yè)務(wù)側(cè)發(fā)現(xiàn)問題
能不能提前感知問題呢?
想了一下, 我們的監(jiān)控更多是在監(jiān)測代碼拋出異常, 對于操作系統(tǒng)的資源缺少監(jiān)控 下一步的優(yōu)化, 對操作系統(tǒng)資源進行監(jiān)控
以上就是線上Spring CPU 高負載解決思路詳解的詳細內(nèi)容,更多關(guān)于線上Spring CPU 高負載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中如何使用Gson將對象轉(zhuǎn)換為JSON字符串
這篇文章主要給大家介紹了關(guān)于Java中如何使用Gson將對象轉(zhuǎn)換為JSON字符串的相關(guān)資料,Gson是Google的一個開源項目,可以將Java對象轉(zhuǎn)換成JSON,也可能將JSON轉(zhuǎn)換成Java對象,需要的朋友可以參考下2023-11-11
IDEA連接MySQL數(shù)據(jù)庫的4種方法圖文教程
IDEA是一種流行的Java開發(fā)工具,可以方便地連接MySQL,這篇文章主要給大家介紹了關(guān)于IDEA連接MySQL數(shù)據(jù)庫的4種方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-12-12
Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法
今天小編就為大家分享一篇關(guān)于Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01
NameNode?重啟恢復(fù)數(shù)據(jù)的流程詳解
這篇文章主要為大家介紹了NameNode?重啟恢復(fù)數(shù)據(jù)的流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
springboot配置文件中使用${}注入值的兩種方式小結(jié)
這篇文章主要介紹了springboot配置文件中使用${}注入值的兩種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

