记一次线上服务器load高问题定位和解决

时间:2024-03-28 09:02:18
1.top 查看load free空间还很大 应该不是GC导致的
分析下面的进程,发现java进程占用了100%的CPU

2.查找java进程下面的哪个线程占用CPU高
ps -ef|grep java 获取PID  4381


top -H -p 4381
通过这个命令发现有一个线程占用了100%的CPU,所以导致load很高,一般占用100%CPU大部分原因是进程阻塞了。下一步跟踪一下这个线程 
线程PID 4529

3.strace追踪线程(root用户才有权限 sudo su 切换)

strace -p 4529

记一次线上服务器load高问题定位和解决

通过日志分析 可以发现有一个线程一直处于等待苏醒的状态,锁一直在同步,判断分析 某个线程出了问题
4.通过jstack命名分析具体代码
printf "%x\n" 4529  转换为16进制
11b1

[[email protected] spring-boot]# jstack 4381|grep llbl


"AchievementEvent-Consumer-Thread-2" #60 daemon prio=5 os_prio=0 tid=0x00007f689161c000 nid=0x11b1 runnable [0x00007f680326b000]
   java.lang.Thread.State: RUNNABLE
    at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:56)
    at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56)
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124)
    at java.lang.Thread.run(Thread.java:748)

"AchievementEvent-Consumer-Thread-2" #64 daemon prio=5 os_prio=0 tid=0x00007f6891630000 nid=0x11b5 waiting on condition [0x00007f6803067000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000758dbc510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
    at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56)
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124)
    at java.lang.Thread.run(Thread.java:748)

通过判断是一个消费者线程一直处于阻塞状态。最后成功找到原因,由于一个异常捕捉之后又重新抛出,导致某个消费者线程B直接挂了,而消费者C一直要等B处理完才能处理,所以C一直处于阻塞状态,并且不断轮询。