轉載自:http://hellojava.info/?p=517java
做者:阿里畢玄程序員
問題排查除了最重要的解決思路和邏輯推導能力外,工具也是不可缺乏的一部分,一個好用的工具能夠事半功倍,甚至在某些狀況下會由於沒有相應的工具而壓根就無法繼續進行下去,這篇文章就來說講在排查Java問題時一般要用到的一些工具(ps:這種文章值得收藏,看一遍其實很容易忘)。 數組
查問題的時候會很是依賴日誌,所以看日誌的相關工具很是重要,一般的話掌握好tail,find,fgrep,awk這幾個經常使用工具的方法就能夠,說到這個就必須說關鍵的異常和信息日誌輸出是多麼的重要(看過太多異常的隨意處理,例如很典型的是應用本身的ServletContextListener實現,不少的Listener實現都會變成往外拋RuntimeException,而後直接致使tomcat退出,而tomcat這個時候也不會輸出這個異常信息,這種時候要查緣由真的是讓人很鬱悶,儘管也有辦法)。
日誌的標準化也很是重要,日誌的標準化一方面方便像我這種要查各類系統問題的人,不標準的話連日誌在哪都找不到;另外一方面對於分佈式系統而言,若是標準化的話是很容易作日誌tracing的,對問題定位會有很大幫助。 tomcat
碰到一些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: 這樣的參數必須是啓動參數的標配。
做爲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類型的問題我排查的不多,因此儘管知道一些工具,仍是不在這裏寫了。
暫時就寫這些,儘管工具的使用多數均可以臨時學,但首先知道有哪些工具是最重要的,而後呢仍是建議你們能夠玩一玩這些工具,這樣之後真的要用的時候也不至於一點印象都沒有。