CPU100排查
saber599

背景

接手的代码在运行时cpu抛高

排查过程

1. 确定进程

通过top命令找出cpu抛高的进程

1
top

截图

2. 确定线程

通过top -Hp 进程号找出cpu抛高的线程

1
top -Hp 39511

截图

3. 确定线程正在执行内容

3.1. 查看堆栈
  1. 将线程号转为16进制
1
printf "%x\n" 40907

截图

  1. 通过jstack查找线程堆栈信息
1
jstack 39511 | grep -A 50 9fcb

截图

3.2. 查看日志

一般情况我们通过查看堆栈信息就能定位到代码出问题所在位置,但这里堆栈信息指向的位置为一个抽象类,该抽象类下面有很多实现类,所以不好确定是哪个类有问题,故而再通过日志再定位具体位置。

1
cat s.log | grep "Thread-14"

截图

4. 分析代码

通过上述的排查过程最终定位到出现问题的类为AbstractQueueListener下面的实现类MonitorBrokerLeaderListener。根据下面的源码可以看出当MonitorBrokerLeaderListener执行handle后,isWorking就会一直为false,AbstractQueueListener中就会出现在循环中一直不会执行handle了,且sleep为0,即出现死循环。
AbstractQueueListener
MonitorBrokerLeaderListener

问题修复

由于写代码的人已经找不到了,只能推测MonitorBrokerLeaderListener作用,该类的作用是想在leader节点间发生漂移后重新同步节点信息以及增加zookeeper节点watcher检测变化,基于该前提下将MonitorBrokerLeaderListener调整为以下内容
MonitorBrokerLeaderListener