Jstack是JDK自带的命令行工具,主要用于线程Dump分析,能得到运行java程序的java stack和native stack的信息,可以轻松得知当前线程的运行情况。
jstack -l [pid]查看所有线程信息 jstack -l 2238 > intsmaze.log [intsmaze@centos-Reall-131 ~]$ jstack -l 2461 "Thread-200": at cn.intsmaze.thread.TestDeadThread.run(TestDeadThread.java:29) - waiting to lock <0x9d62a3a0> (a java.lang.Integer) at java.lang.Thread.run(Thread.java:748) "Thread-10": at cn.intsmaze.thread.TestDeadThread.run(TestDeadThread.java:30) - waiting to lock <0x9d62a390> (a java.lang.Integer) - locked <0x9d62a3a0> (a java.lang.Integer) at java.lang.Thread.run(Thread.java:748)jstack命令生成的thread dump信息包含了JVM中所有存活的线程,为了分析指定线程,必须找出对应线程的调用栈,应该如何找?
jstack -l [pid] | grep 16进制top -Hp [pid] 中获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread dump中每个线程都有一个nid,找到对应的nid即可。
得到2462 的十六进制值 ··· [intsmaze@centos-Reall-131 ~]$ printf "%x\n" 2462 99e ··· jstack -l 21711 | grep 99e "PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x99e in Object.wait()在nid=0x99e 的线程调用栈中,CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),然后去观察自己写的业务代码。
源码插桩 当初小弟运气好,做了一个比较核心的红包业务,基本上每周都会有新的版本发布。而且面对的人群是普通用户,用户一发现消费没有中红包,就会打客服,然后我这边就会收到反馈,这个时候就要根据客户的交易id查询原因给出反馈。如果当初在开发的时候,没有考虑到源码插桩,那么这个时候我就会头疼,推出去的报文相应字段确实没有中红包,然后我去看规则是否是这笔交易没有满足,然后找了几天还是没有给出让人信服的答案。在这个系统架构师对我们所有的系统做了源码插桩,一条记录从进入系统,走过那些条件判断的流程,每一个条件判断的值都进行了插桩,然后汇聚成一条消息处理记录存储在hbase。然后面对这种情况,我们只需要去hbase中查询一下,拿出这条消息在整个系统的路径状况变一目了然了。