转载自: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类型的问题我排查的不多,因此尽管知道一些工具,仍是不在这里写了。
暂时就写这些,尽管工具的使用多数均可以临时学,但首先知道有哪些工具是最重要的,而后呢仍是建议你们能够玩一玩这些工具,这样之后真的要用的时候也不至于一点印象都没有。