標籤:輸出 工具箱 中斷 exception 應用 print int 情況 印象
轉載自: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類型的問題我排查的很少,所以儘管知道一些工具,還是不在這裡寫了。
暫時就寫這些,儘管工具的使用多數都可以臨時學,但首Crowdsourced Security Testing道有哪些工具是最重要的,然後呢還是建議大家可以玩一玩這些工具,這樣以後真的要用的時候也不至於一點印象都沒有。
Java問題排查工具箱[轉載]