轉載自:http://hellojava.info/?p=517
作者:阿裡畢玄
問題排查除了最重要的解決思路和邏輯推導能力外,工具也是不可缺少的一部分,一個好用的工具可以事半功倍,甚至在某些情況下會因為沒有相應的工具而壓根就沒法繼續進行下去,這篇文章就來講講在排查java問題時通常要用到的一些工具(ps:這種文章值得收藏,看一遍其實很容易忘)。
日志相關工具
查問題的時候會非常依賴日志,是以看日志的相關工具非常重要,通常的話掌握好tail,find,fgrep,awk這幾個常用工具的方法就可以,說到這個就必須說關鍵的異常和資訊日志輸出是多麼的重要(看過太多異常的随意處理,例如很典型的是應用自己的servletcontextlistener實作,很多的listener實作都會變成往外抛runtimeexception,然後直接導緻tomcat退出,而tomcat這個時候也不會輸出這個異常資訊,這種時候要查原因真的是讓人很郁悶,盡管也有辦法)。
日志的标準化也非常重要,日志的标準化一方面友善像我這種要查各種系統問題的人,不标準的話連日志在哪都找不到;另一方面對于分布式系統而言,如果标準化的話是很容易做日志tracing的,對問題定位會有很大幫助。
cpu相關工具
碰到一些cpu相關的問題時,通常需要用到的工具:
top (-h)
top可以實時的觀察cpu的名額狀況,尤其是每個core的名額狀況,可以更有效的來幫助解決問題,-h則有助于看是什麼線程造成的cpu消耗,這對解決一些簡單的耗cpu的問題會有很大幫助。
sar
sar有助于檢視曆史名額資料,除了cpu外,其他記憶體,磁盤,網絡等等各種名額都可以檢視,畢竟大部分時候問題都發生在過去,是以翻曆史記錄非常重要。
jstack
jstack可以用來檢視java程序裡的線程都在幹什麼,這通常對于應用沒反應,非常慢等等場景都有不小的幫助,jstack預設隻能看到java棧,而jstack -m則可以看到線程的java棧和native棧,但如果java方法被編譯過,則看不到(然而大部分經常通路的java方法其實都被編譯過)。
pstack
pstack可以用來看java程序的native棧。
perf
一些簡單的cpu消耗的問題靠着top -h + jstack通常能解決,複雜的話就需要借助perf這種超級利器了。
cat /proc/interrupts
之是以提這個是因為對于分布式應用而言,頻繁的網絡通路造成的網絡中斷處理消耗也是一個關鍵,而這個時候網卡的多隊列以及均衡就非常重要了,是以如果觀察到cpu的si名額不低,那麼看看interrupts就有必要了。
記憶體相關工具
碰到一些記憶體相關的問題時,通常需要用到的工具:
jstat
jstat -gcutil或-gc等等有助于實時看gc的狀況,不過我還是比較習慣看gc log。
jmap
在需要dump記憶體看看記憶體裡都是什麼的時候,jmap -dump可以幫助你;在需要強制執行fgc的時候(在cms gc這種一定會産生碎片化的gc中,總是會找到這樣的理由的),jmap -histo:live可以幫助你(顯然,不要随便執行)。
gcore
相比jmap -dump,其實我更喜歡gcore,因為感覺就是更快,不過由于某些jdk版本貌似和gcore配合的不是那麼好,是以那種時候還是要用jmap -dump的。
mat
有了記憶體dump後,沒有分析工具的話然并卵,mat是個非常贊的工具,好用的沒什麼可說的。
btrace
少數的問題可以mat後直接看出,而多數會需要再用btrace去動态跟蹤,btrace絕對是java中的超級神器,舉個簡單例子,如果要你去查下一個運作的java應用,哪裡在建立一個數組大小>1000的arraylist,你要怎麼辦呢,在有btrace的情況下,那就是秒秒鐘搞定的事,:)
gperf
java堆内的記憶體消耗用上面的一些工具基本能搞定,但堆外就悲催了,目前看起來還是隻有gperf還算是比較好用的一個,或者從經驗上來說direct bytebuffer、deflater/inflater這些是常見問題。
除了上面的工具外,同樣記憶體資訊的記錄也非常重要,就如日志一樣,是以像gc日志是一定要打開的,確定在出問題後可以翻查gc日志來對照是否gc有問題,是以像-xx:+printgcdetails -xx:+printgcdatestamps -xloggc: 這樣的參數必須是啟動參數的标配。
classloader相關工具
作為java程式員,不碰到classloader問題那基本是不可能的,在排查此類問題時,最好辦的還是-xx:+traceclassloading,或者如果知道是什麼類的話,我的建議就是把所有會裝載的lib目錄裡的jar用jar -tvf *.jar這樣的方式來直接檢視沖突的class,再不行的話就要呼喚btrace神器去跟蹤classloader.defineclass之類的了。
其他工具
jinfo
java有n多的啟動參數,n多的預設值,而任何文檔都不一定準确,隻有用jinfo -flags看到的才靠譜,甚至你還可以看看jinfo -flag,你會發現更好玩的。
dmesg
你的java程序突然不見了? 也許可以試試dmesg先看看。
systemtap
有些問題排查到java層面是不夠的,當需要trace更底層的os層面的函數調用的時候,systemtap神器就可以派上用場了。
gdb
更進階的玩家們,拿着core dump可以用gdb來排查更詭異的一些問題。
io類型的問題我排查的很少,是以盡管知道一些工具,還是不在這裡寫了。
暫時就寫這些,盡管工具的使用多數都可以臨時學,但首先知道有哪些工具是最重要的,然後呢還是建議大家可以玩一玩這些工具,這樣以後真的要用的時候也不至于一點印象都沒有。