CPU 使用率是衡量系統(tǒng)繁忙程度的重要指標(biāo),一般情況下單純的 CPU 高并沒有問題,它代表系統(tǒng)正在不斷的處理我們的任務(wù),但是如果 CPU 過高,導(dǎo)致任務(wù)處理不過來,從而引起 load 高,這個是非常危險需要關(guān)注的。 CPU 使用率的安全值沒有一個標(biāo)準值,取決于你的系統(tǒng)是計算密集型還是 IO 密集型,一般計算密集型應(yīng)用 CPU 使用率偏高 load 偏低,IO 密集型相反。 1 頻繁 FullGC/YongGC 2 代碼消耗,如死循環(huán),md5 等內(nèi)存態(tài)操作 1)arthas (已開源:https://github.com/alibaba/arthas) 2)jstack 查找  ps:輸入“1”可查看每個 CPU 的情況,之前有團隊遇到單個 CPU 被中間件綁定導(dǎo)致 CPU 飚高的 case。load 指單位時間內(nèi)活躍進程數(shù),包含運行態(tài)(runnable 和 running)和不可中斷態(tài)( IO、內(nèi)核態(tài)鎖)。關(guān)鍵字是運行態(tài)和不可中斷態(tài),運行態(tài)可以聯(lián)想到 Java 線程的 6 種狀態(tài),如下,線程 new 之后處于 NEW 狀態(tài),執(zhí)行 start 進入 runnable 等待 CPU 調(diào)度,因此如果 CPU 很忙會導(dǎo)致 runnable 進程數(shù)增加;不可中斷態(tài)主要包含網(wǎng)絡(luò) IO、磁盤 IO 以及內(nèi)核態(tài)的鎖,如 synchronized 等。 1 CPU 利用率高,可運行態(tài)進程數(shù)多2 iowait,等待 IO 3 等待內(nèi)核態(tài)鎖,如 synchronized在了解 FullGC 原因之前,先花一點時間回顧下 jvm 的內(nèi)存相關(guān)知識:新 new 的對象放在 Eden 區(qū),當(dāng) Eden 區(qū)滿之后進行一次 MinorGC,并將存活的對象放入 S0; 當(dāng)下一次 Eden 區(qū)滿的時候,再次進行 MinorGC,并將存活的對象和 S0 的對象放入S1(S0 和 S1 始終有一個是空的); 依次循環(huán)直到 S0 或者 S1 快滿的時候?qū)ο蠓湃?old 區(qū),依次,直到 old 區(qū)滿進行 FullGC。 jdk1.7 之前 Java 類信息、常量池、靜態(tài)變量存儲在 Perm 永久代,類的原數(shù)據(jù)和靜態(tài)變量在類加載的時候放入 Perm 區(qū),類卸載的時候清理;在 1.8 中,MetaSpace 代替 Perm 區(qū),使用本地內(nèi)存,常量池和靜態(tài)變量放入堆區(qū),一定程度上解決了在運行時生成或加載大量類造成的 FullGC,如反射、代理、groovy 等。 年輕代常用 ParNew,復(fù)制算法,多線程并行;老年代常用 CMS,標(biāo)記清除算法(會產(chǎn)生內(nèi)存碎片),并發(fā)收集(收集過程中有用戶線程產(chǎn)生對象)。從S區(qū)晉升的對象在老年代也放不下導(dǎo)致 FullGC(fgc 回收無效則拋 OOM)。1)survivor 區(qū)太小,對象過早進入老年代。 2)大對象分配,沒有足夠的內(nèi)存。 在 CMS GC 過程中業(yè)務(wù)線程將對象放入老年代(并發(fā)收集的特點)內(nèi)存不足。詳細原因:1)fgc 觸發(fā)比例過大,導(dǎo)致老年代占用過多,并發(fā)收集時用戶線程持續(xù)產(chǎn)生對象導(dǎo)致達到觸發(fā) FGC 比例。 2)老年代存在內(nèi)存碎片。 Java 線程池以有界隊列的線程池為例,當(dāng)新任務(wù)提交時,如果運行的線程少于 corePoolSize,則創(chuàng)建新線程來處理請求。如果正在運行的線程數(shù)等于 corePoolSize 時,則新任務(wù)被添加到隊列中,直到隊列滿。當(dāng)隊列滿了后,會繼續(xù)開辟新線程來處理任務(wù),但不超過 maximumPoolSize。當(dāng)任務(wù)隊列滿了并且已開辟了最大線程數(shù),此時又來了新任務(wù),ThreadPoolExecutor 會拒絕服務(wù)。2 數(shù)據(jù)庫慢 sql 或者數(shù)據(jù)庫死鎖常見問題 5:NoSuchMethodException java 在裝載一個目錄下所有 jar 包時,它加載的順序完全取決于操作系統(tǒng)。阿里巴巴開源 Java 診斷工具(開源地址:https://github.com/alibaba/arthas),基于 javaAgent 方式,使用 Instrumentation 方式修改字節(jié)碼方式進行 Java 應(yīng)用診斷。watch xxxClass xxxMethod ' {params, throwExp} ' -e -x 2watch xxxClass xxxMethod '{params,returnObj}' 'params[0].sellerId.equals('189')' -x 2watch xxxClass xxxMethod sendMsg '@com.taobao.eagleeye.EagleEye@getTraceId()'1 線程池滿 高 RT 接口進行線程數(shù)限流 重啟可短暫緩解,具體還得看問題原因 kill 進程 sql 限流 線上問題的排查是一個積累的過程,只有了解問題背后的原理才能更快速的定位和恢復(fù),除此之外更需要有一些趁手的工具來輔助排查,從而降低整個團隊問題定位和快恢的門檻。
|