java線上服務問題排查
1、業務日誌相關
如果應用系統出現異常,一般都會在業務日誌中體現
統計當天業務日誌中ERROR出現數量:egrep ERROR --color logname | wc -l ,如果錯誤數量過大,一般都是有問題的
查看日誌中ERROR後10行具體報錯:egrep -A 10 ERROR logname | less ,或 -C 10 查看ERROR前後10行日誌
- Java中,所有異常都繼承自Throwable類(一個完整可用的類)。整體上分爲Error、Exception兩個大類,Exception大類又分爲UncheckedException(繼承於RuntimeException)和CheckedException(繼承於Exception,但不繼承於RuntimeException)。
常見異常關鍵字有:ERROR、Exception
ERROR:AssertionError、OutOfMemoryError、StackOverflowError
UncheckedException:AlreadyBoundException、ClassCastException、ConcurrentModificationException、IllegalArgumentException、IllegalStateException、IndexOutOfBoundsException、JSONException、NullPointerException、SecurityException、UnsupportedOperationException
CheckedException:ClassNotFoundException、CloneNotSupportedException、FileAlreadyExistsException、FileNotFoundException、InterruptedException、IOException、SQLException、TimeoutException、UnknownHostException
# 上述參考:http://www.importnew.com/27348.html
- 以時間段查看日誌、先查看日誌的時間格式,使用sed命令截取特定時間段日誌,在過濾異常關鍵字,如下:
sed -n '/起始時間/,/結束時間/p' 日誌文件
sed -n '/2018-12-06 00:00:00/,/2018-12-06 00:03:00/p' logname # 查詢三分鐘內的日誌,後再跟grep 過濾相應關鍵字
sed -n '/2018-12-06 08:38:00/,$p' logname | less # 查詢指定時間到當前日誌
# ps:禁止使用vim直接打開日誌文件
2、數據庫相關
Java應用非常多瓶頸在數據庫,一條sql沒寫好導致慢查詢,可能會導致整個應用掛起
- 關注日誌中出現的Could not get JDBC Connection,JDBCException
- 參考:http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/JDBCException.html
此時需要查看數據庫連接請求、是否連接數過大,是否出現死鎖、查看數據庫慢日誌定位具體SQL
3、JVM相關
Java虛擬機相關的問題一般多是下面幾種問題:gc時間過長、OOM、死鎖、線程block、線程數暴漲等問題。一般通過下面幾個工具都能定位出問題。
- 常用的JDK監控和故障處理工具:jps, jstack, jmap、jstat, jconsole, jinfo, jhat, javap, btrace、TProfiler
名稱 主要作用
jps JVM Process Status Tool,用來查看基於HotSpot的JVM裏面中,所有具有訪問權限的Java進程的具體狀態, 包括進程ID,進程啓動的路徑及啓動參數等等,與unix上的ps類似,只不過jps是用來顯示java進程,可以把jps理解爲ps的一個子集。
jstat JVM Statistics Monitoring Tool,jstat是用於監視虛擬各種運行狀態信息的命令行工具,它可以顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
jinfo Configuration info for java,命令的作用是實時的查看和調整虛擬機的參數。
jmap Memory Map for java,生成虛擬機的內存轉儲快照(heapdump)
jhat JVM Heap Dump Browser,用於分析heapdump文件,它會建立一個Http/HTML服務器,讓用戶可以在瀏覽器上查看分析結果
jstack Stack Trace for java,顯示虛擬機的線程快照。
使用--help,查看命令具體使用
常用:
jps -v
jstat -gc 118694 500 5
jmap -dump:live,format=b,file=dump.hprof 29170
jmap -heap 29170
jmap -histo:live 29170 | more
jmap -permstat 29170
jstack -l 29170 |more
參考連接:
- JVM性能調優監控工具jps、jstack、jmap、jhat、jstat使用詳解:https://blog.csdn.net/wisgood/article/details/25343845
- JVM的常用性能監控工具jps、jstat、jinfo、jmap、jhat、jstack:https://blog.csdn.net/u010316188/article/details/80215884
- JVM系列五:JVM監測&工具[整理中]:https://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html
- jvm系列五:監測命令(jvisualvm jps jstat jmap jhat jstack jinfo)及dump堆內存快照分析:https://blog.csdn.net/xybelieve1990/article/details/53516437
- JVM學習之jstat使用方法:https://www.cnblogs.com/parryyang/p/5772484.html
- jstat命令查看jvm的GC情況 (以Linux爲例):https://www.cnblogs.com/yjd_hycf_space/p/7755633.html
- java進程CPU過高排查:https://www.cnblogs.com/Dhouse/p/7839810.html
- https://stackify.com/java-performance-tools-8-types-tools-need-know/
- https://stackoverflow.com/questions/97599/static-analysis-tool-recommendation-for-java
3.1、OOM相關
發生OOM問題一般服務都會crash,業務日誌會有OutOfMemoryError。
- OOM一般都是出現了內存泄露,須要查看OOM時候的jvm堆的快照,假設配置了-XX:+HeapDumpOnOutOfMemoryError, 在發生OOM的時候會在-XX:HeapDumpPath生成堆的dump文件。結合MAT,能夠對dump文件進行分析。查找出發生OOM的原因.
- 關於MAT使用不詳述了,google上一堆(http://inter12.iteye.com/blog/1407492)。
ps:
1、server的內存一般較大,所以要保證server的磁盤空間大於內存大小
2、另外手動dump堆快照。能夠使用命令jmap -dump:format=b,file=file_name pid 或者kill -3 pid
3.2、死鎖
死鎖原因是兩個或者多個線程相互等待資源。現象通常是出現線程hung住。更嚴重會出現線程數暴漲,系統出現api alive報警等。查看死鎖最好的方法就是分析當時的線程棧。
# 詳細case 能夠參考jstack命令裏面的樣例
用到的命令:
jps -v
jstack -l pid
3.3、線程block、線程數暴漲
jstack -l pid |wc -l
jstack -l pid |grep "BLOCKED"|wc -l
jstack -l pid |grep "Waiting on condition"|wc -l
線程block問題通常是等待io、等待網絡、等待監視器鎖等造成,可能會導致請求超時、造成造成線程數暴漲導致系統502等。
假設出現這樣的問題,主要是關注jstack 出來的BLOCKED、Waiting on condition、Waiting on monitor entry等狀態信息。
假設大量線程在“waiting for monitor entry”:可能是一個全局鎖堵塞住了大量線程。
假設短時間內打印的 thread dump 文件反映。隨着時間流逝。waiting for monitor entry 的線程越來越多,沒有降低的趨勢,可能意味着某些線程在臨界區裏呆的時間太長了,以至於越來越多新線程遲遲無法進入臨界區。
假設大量線程在“waiting on condition”:可能是它們又跑去獲取第三方資源,遲遲獲取不到Response,導致大量線程進入等待狀態。
假設發現有大量的線程都處在 Wait on condition,從線程堆棧看,正等待網絡讀寫,這可能是一個網絡瓶頸的徵兆,由於網絡堵塞導致線程無法運行。
3.4、gc時間過長
4、Server本身問題
- 排查:CPU、Memory、IO、Network
- 常用命令:top/htop 、free、iostat/iotop、netstat/ss
關注網絡連接:
查看tcp各個狀態數量:netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
查看連接某服務端口最多的IP:netstat -na | grep 172.16.70.60:1111 | awk '{print $5}' | cut -d : -f1 | sort | uniq -c | sort -rn | head -10