Java問題排查工具箱
-
問題排查
- 解決思路,邏輯推導(dǎo)
- 工具
-
日志相關(guān)工具
- 日志的標準化
- to be continued...
- tail
- tail -f app-server.log
- tail -n 300 app-server.log
- find
- fgrep
- awk
- grep -C/A/B 30 'aaa' app-server.log
- 日志的標準化
-
CPU相關(guān)工具
-
top (real-time 觀察系統(tǒng)的情況)
- top
- top -Hp <pid>
- top (press 1 show multi-cores, press 1 again to close, press q exit)
-
sar
- 查看歷史指標數(shù)據(jù),除了CPU外静陈,其他內(nèi)存呼寸,磁盤殿如,網(wǎng)絡(luò)等等各種指標都可以查看
-
jstack
- 通常對于應(yīng)用沒反應(yīng)祖驱,非常慢等等場景
- jstack默認只能看到Java棧茶没,而jstack -m則可以看到線程的Java棧和native棧秒咨,但如果Java方法被編譯過稚瘾,則看不到(然而大部分經(jīng)常訪問的Java方法其實都被編譯過)
- -F 走JDK SA
- /proc/<pid>/mappings
- ptrace(PTRACE_ATTACH, PTRACE_PEEKDATA)
- 默認或-l走JDK Attach mechanism
- -m or -F走JDK SA mechanism
- java的tda工具就是專門分析thread dump的
- 在線分析工具
- kill -3 $PID / kill -QUIT $PID tomcat會把thread dump的內(nèi)容輸出到控制臺
- We can use kill -3 PID command to generate the thread dump. This is slightly different from other ways to generate thread dump. When kill command is issued, thread dump is generated to the System out of the program. So if it’s a java program with console as system out, the thread dump will get printed on the console. If the java program is a Tomcat server with system out as catalina.out, then thread dump will be generated in the file.
死鎖,Deadlock(重點關(guān)注)
執(zhí)行中周霉,Runnable
等待資源掂器,Waiting on condition(重點關(guān)注)
等待獲取監(jiān)視器,Waiting on monitor entry(重點關(guān)注)
暫停俱箱,Suspended
對象等待中国瓮,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重點關(guān)注)
停止,Parked
-
jcmd
- Java 8 has introduced jcmd utility. You should use this instead of jstack if you are on Java 8 or higher. Command to generate thread dump using jcmd is jcmd PID Thread.print.
-
pstack
- pstack可以用來看Java進程的native棧
-
perf
- 一些簡單的CPU消耗的問題靠著top -H + jstack通常能解決乃摹,復(fù)雜的話就需要借助perf這種超級利器了
-
cat /proc/interrupts
- 之所以提這個是因為對于分布式應(yīng)用而言禁漓,頻繁的網(wǎng)絡(luò)訪問造成的網(wǎng)絡(luò)中斷處理消耗也是一個關(guān)鍵,而這個時候網(wǎng)卡的多隊列以及均衡就非常重要了孵睬,所以如果觀察到cpu的si指標不低播歼,那么看看interrupts就有必要了
-
-
內(nèi)存相關(guān)工具
- jstat
- jstat -gcutil或-gc等等有助于實時看gc的狀況,不過我還是比較習(xí)慣看gc log
- *.gc日志查看 or http://gceasy.io這個網(wǎng)站支持gc日志分析, *.gz or *.zip
- jmap
- memory dump分析內(nèi)存泄漏
- 在需要dump內(nèi)存看看內(nèi)存里都是什么的時候肪康,jmap -dump可以幫助你荚恶;在需要強制執(zhí)行fgc的時候(在CMS GC這種一定會產(chǎn)生碎片化的GC中,總是會找到這樣的理由的)磷支,jmap -histo:live可以幫助你(顯然,不要隨便執(zhí)行)食寡。
- gcore
- 相比jmap -dump雾狈,其實我更喜歡gcore,因為感覺就是更快抵皱,不過由于某些jdk版本貌似和gcore配合的不是那么好善榛,所以那種時候還是要用jmap -dump的
- eclipse mat
- 有了內(nèi)存dump后,沒有分析工具的話然并卵呻畸,mat是個非常贊的工具移盆,好用的沒什么可說的?
- 我傾向于用IBM Memory Analyzer
- btrace
- 少數(shù)的問題可以mat后直接看出,而多數(shù)會需要再用btrace去動態(tài)跟蹤伤为,btrace絕對是Java中的超級神器咒循,舉個簡單例子,如果要你去查下一個運行的Java應(yīng)用绞愚,哪里在創(chuàng)建一個數(shù)組大小>1000的ArrayList叙甸,你要怎么辦呢,在有btrace的情況下位衩,那就是秒秒鐘搞定的事
- gperf
- Java堆內(nèi)的內(nèi)存消耗用上面的一些工具基本能搞定裆蒸,但堆外就悲催了,目前看起來還是只有g(shù)perf還算是比較好用的一個糖驴,或者從經(jīng)驗上來說Direct ByteBuffer僚祷、Deflater/Inflater這些是常見問題
- jstat
除了上面的工具外,同樣內(nèi)存信息的記錄也非常重要贮缕,就如日志一樣辙谜,所以像GC日志是一定要打開的,確保在出問題后可以翻查GC日志來對照是否GC有問題跷睦,所以像-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc: 這樣的參數(shù)必須是啟動參數(shù)的標配
-
ClassLoader相關(guān)工具
- 作為Java程序員筷弦,不碰到ClassLoader問題那基本是不可能的,在排查此類問題時,最好辦的還是-XX:+TraceClassLoading烂琴,或者如果知道是什么類的話爹殊,我的建議就是把所有會裝載的lib目錄里的jar用jar -tvf *.jar這樣的方式來直接查看沖突的class,再不行的話就要呼喚btrace神器去跟蹤Classloader.defineClass之類的了
-
其他工具
- jinfo
- Java有N多的啟動參數(shù)奸绷,N多的默認值梗夸,而任何文檔都不一定準確,只有用jinfo -flags看到的才靠譜号醉,甚至你還可以看看jinfo -flag反症,你會發(fā)現(xiàn)更好玩的
- dmesg
- 你的java進程突然不見了? 也許可以試試dmesg先看看
- systemtap
- 有些問題排查到j(luò)ava層面是不夠的畔派,當需要trace更底層的os層面的函數(shù)調(diào)用的時候铅碍,systemtap神器就可以派上用場了
- gdb
- 更高級的玩家們,拿著core dump可以用gdb來排查更詭異的一些問題
- jinfo
暫時就寫這些线椰,盡管工具的使用多數(shù)都可以臨時學(xué)胞谈,但首先知道有哪些工具是最重要的,然后呢還是建議大家可以玩一玩這些工具憨愉,這樣以后真的要用的時候也不至于一點印象都沒有
-
References