java應用監測(4)-線上問題排查套路

tags: java, troubleshooting, monitorhtml


一句話歸納:java應用線上問題如CPU太高,內存溢出,IO太高等問題如何排查,本文爲你詳細講述。java

1 引言

java應用上線運行後,免不了會有各類問題,總的來講問題會分爲四大類:ios

  • (1)CPU相關問題
  • (2)內存相關問題
  • (3)磁盤及IO相關問題
  • (4)業務代碼問題。

針對這些問題,線上如何進行監測與問題排查,是一個java開發人員的必要技能。下面將結合前面提到的java命令行工具,對這幾個問題的排查套路進行說明。git

2 CPU問題排查套路

若是發現系統變慢變卡,應用響應變慢,首先要查的就是CPU使用狀況,通常是進程佔用CPU太高,所以須要監測CPU的佔用狀況,而java應用中與CPU相關的主要是線程的運行,所以具體到java應用,須要監測線程的運行狀態,對應就是命令行工具jstack。所以,總結CPU佔用太高問題可按下面套路:程序員

# (1) 查詢CPU佔用高的進程ID(PID)
top -c
 # (2) 瞭解此進程的啓動參數
ps -ef|grep  PID
或者
jinfo -flags PID
 # (3) 打印線程堆棧信息並輸出文件
jstack -l PID > PID.dump
 # (4) 根據進程查找線程ID(TID)
top -H -p PID
 # (5) 獲取TID的16進制數
printf "%x\n" TID
 # (6) 結合TID和線程堆棧信息文件查找問題
- 可使用文本工具直接查看
- 可使用 grep TID -A20 PID.dump 來查看
- 須要配合線程狀態來檢查

複製代碼

關於jstack工具和線程狀態可查看文章《java應用監測(3)-這些命令行工具你掌握了嗎》github

3 內存問題排查套路

內存問題主要是java應用在運行過程當中發生OOM(out of memory),所以須要建議在java應用啓動時,添加幾個參數,包括-Xloggc:file -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/heapdump.hprof -XX:ErrorFile=logs/java_error_%p.log。這樣當發生oom時,能夠從dump出來的文件來分析oom的緣由。與內存問題相關的java命令行工具包括jmap,jstat,所以內存OOM問題排查套路以下:shell

# (1)找到java應用進程(PID)
jps -lvm
或者
top -c
 # (2)瞭解此進程啓動參數(特別是-Xms,-Xmx等)
ps -ef|grep  PID
或者
jinfo -flags PID
 # (3) 確認內存狀況
jmap -heap PID
 # (4) 查找佔內存的大對象
jmap -histo:live PID 
 # (5) dump出堆文件,以便使用工具分析
jmap -dump:file=./heap.hprof PID
 # (6) 查看GC變化狀況,以下每秒打印一次
jstat -gc PID 1000 
 # (7) 結合日誌文件出錯信息及dump出來的堆文件分析OOM和GC狀況
- 內存分配小,適當調整內存
- 對象被頻繁建立,且不釋放,優化代碼
- young gc頻率過高,查看-Xmn、-XX:SurvivorRatio等參數設置是否合理
複製代碼

關於OOM,官方文檔有關於OOM的說明(https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html), 主要分爲如下幾大類:數組

  • java.lang.OutOfMemoryError: Java heap space,堆的內存佔用已經達到-Xmx設置的最大值,沒法建立新對象,簡單的能夠考慮經過調整-Xmx參數來解決。
  • java.lang.OutOfMemoryError: GC Overhead limit exceeded,表示GC一直在執行且java進程運行很慢,一般會拋出此異常,java堆的分配的空間很小以致於新數據沒法放到堆中。考慮調整堆大小,若是想關閉此輸出,可用參數來關閉-XX:-UseGCOverheadLimit
  • java.lang.OutOfMemoryError: Requested array size exceeds VM limit,java應用嘗試分配大於堆大小的數組,如堆大小是256M,卻要分配512M的數組,則會報錯。考慮調整堆大小或者修改代碼
  • java.lang.OutOfMemoryError: Metaspace,當類元數據所需的本機內存量超過期MaxMetaSpaceSize時報出,考慮調整MaxMetaSpaceSize。
  • java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?當來自本機堆的分配失敗而且本機堆可能接近耗盡時會報此錯誤,須要查看日誌來處理。
  • java.lang.OutOfMemoryError: Compressed class space,JVM的非堆結構中,類指針存放空間不足,考慮使用CompressedClassSpaceSize來調整。
  • java.lang.OutOfMemoryError: reason stack_trace_with_native_method,JVM的本地方法區不足,在Java本機接口(JNI)或本機方法中檢測到分配失敗,須要查找對應堆棧信息來查詢。

4 磁盤及IO問題排查套路

java應用運行過程當中,會涉及日誌產生,對磁盤的讀寫等操做,也有可能有各類問題,如磁盤不足(日誌輸出過多)、、磁盤讀寫IO比較慢、IO過於頻繁等。通常來講,能夠按如下套路進行排查:bash

# (1) 查看磁盤容量狀況
df -h
 # (2) 查看文件大小和目錄大小
ls -l 或者直接ll
du -h --max-depth=1
 # (3) 查看IO狀況,找到IO讀寫頻繁的進程PID
iotop -d 1 # 1秒打印一次
或者
iostat -d -x -k 1 #1秒打印一次
 # (4) 使用stack打印線程堆棧信息,排查IO相關代碼
 # (5) 有時候若想測試磁盤的讀寫速度(特別是虛擬機),可使用dd
# 示例:測數據卷掛載目錄的純寫速度
dd if=/dev/zero of=/數據卷目錄/test.iso bs=8k count=1000000

複製代碼

5 業務問題排查套路

業務問題,主要是涉及到代碼邏輯層面的,主要是查詢日誌輸出,方法是否按正確的邏輯執行,所以通常的排查套路以下:oracle

# (1) 實時日誌輸出查詢
tail -fn 100 log_file
 # (2) 根據日誌輸出的關鍵字來定位問題
grep keyWord log_file # 關鍵字所在行
grep -C n keyWord log_file # 關鍵字所在先後n行
 # (3) 日誌文件使用可視化文本工具分析(notepad++,sublime,大文件查看如EmEditor)
 # (4) 使用線上工具直接檢測方法的參數、返回值,異常狀況等等,如Btrace,arthas等。

複製代碼

關於java線上問題的診斷工具包括Btrace及arthas,本系列後續會有相應的文章進行介紹。

6 總結

本文對java應用線上遇到的問題分爲四大類,分別是(1)CPU相關問題,(2)內存相關問題,(3)磁盤及IO相關問題,(4)業務代碼問題。針對各類問題,按照必定的套路,結合java的命令行工具和線上診斷工具,能夠很方便地給java應用進行排查。但願本文給相應的java開發人員有幫助。

參考資料

相關閱讀

相關文章
相關標籤/搜索