CPU100排查
背景
接手的代码在运行时cpu抛高
排查过程
1. 确定进程
通过top命令找出cpu抛高的进程
1 | top |
2. 确定线程
通过top -Hp 进程号找出cpu抛高的线程
1 | top -Hp 39511 |
3. 确定线程正在执行内容
3.1. 查看堆栈
- 将线程号转为16进制
1 | printf "%x\n" 40907 |
- 通过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,即出现死循环。
问题修复
由于写代码的人已经找不到了,只能推测MonitorBrokerLeaderListener作用,该类的作用是想在leader节点间发生漂移后重新同步节点信息以及增加zookeeper节点watcher检测变化,基于该前提下将MonitorBrokerLeaderListener调整为以下内容