上上周生产出现问题,记录一下定位问题的方案,原创不易,欢迎关注
测试代码:
@RestController
@RequestMApping("/test")
public class TestController {
private static Logger log = LoggerFactory.getLogger(TestController.class);
@GetMapping("/test")
public boolean test(){
Thread t1 = new Thread(new ThreadOne());
t1.setName("one");
Thread t2 = new Thread(new ThreadTwo());
t2.setName("two");
t1.start();
t2.start();
return true;
}
public class ThreadOne implements Runnable {
public void run() {
int a = 0;
while (true) {
a++;
try {
log.info("[ThreadOne]当前a等于:{}",a);
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadTwo implements Runnable {
public void run() {
long a = 0L;
while (true) {
a++;
log.info("[ThreadTwo]当前a等于:{}",a);
}
}
}
}
触发:
第一种方式:
1、top找到占用CPU最多的进程
2、top -Hp pid 找出8139进程中耗用CPU最多的线程,按H,获取每个线程的内存情况
top -Hp 8139
3、printf "%xn" pid 将线程id转成十六进制
4、执行jstack命令,得到线程堆栈信息中12509这个线程所在行的后面20行
jstack 8139 |grep 30dd -A 20 >test.txt
5、将test.txt文件下载到本地,打开就能看到具体的堆栈信息,最后找出可能存在问题的代码
这个几个命令确实找到问题,但是整体敲下来需要一点时间,生产环境出现问题,需要争分夺秒,不然损失很大,也可能造成数据积压。下面推荐一个阿里大神写的一段脚本,只需要三步就可以搞定
第二种:使用show-busy-JAVA-threads快速排查Java的CPU性能问题
下载
wget --no-check-certificate https://raw.github.com/oldratlee/useful-scripts/release/show-busy-java-threads
添加执行权限
chmod +x show-busy-java-threads
启动
./show-busy-java-threads或者 sh show-busy-java-threads
显然,结果跟第一种一样。你学会了吗,哈哈