AlmaLinux服务器Java进程QTP线程池CPU占用过高排查求助
AlmaLinux上Jetty QTP线程WAITING状态高CPU占用排查方案
问题描述
我的AlmaLinux服务器上有一个Java进程CPU占用率超过400%,不符合预期。分析后发现多个Jetty的Queued Thread Pool(QTP,队列线程池)线程在消耗CPU:
通过线程转储(Thread Dump)匹配NID后,发现高CPU的QTP线程处于WAITING和TIMED_WAITING状态,例如:
NID为3221507的线程单独消耗21%CPU:
"qtp737077247-58814" #58814 prio=5 os_prio=0 tid=0x00007f60e0002000 nid=0x312803 runnable [0x00007f61125f0000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000ed507048> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:392) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:546) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$800(QueuedThreadPool.java:47) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:609) at java.lang.Thread.run(Thread.java:750)
再比如NID为3183314的线程消耗23%CPU:
"qtp737077247-58803" #58803 prio=5 os_prio=0 tid=0x00007f60fc001800 nid=0x3092d2 waiting on condition [0x00007f61b1606000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000ed507028> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209) at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285) at org.eclipse.jetty.util.BlockingArrayQueue.offer(BlockingArrayQueue.java:302) at org.eclipse.jetty.util.thread.QueuedThreadPool.execute(QueuedThreadPool.java:374) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:207) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572) at java.lang.Thread.run(Thread.java:750)
无法理解为何处于WAITING状态的线程会消耗大量CPU,已查阅相关问题未获有效帮助。相同进程在Windows机器上运行时CPU占用正常,无此类问题。
排查方向
- 检查JVM与Linux内核兼容性:对比Windows和Linux上的JVM厂商(OpenJDK/Oracle JDK)、版本,尝试升级/降级JVM到稳定版本,排查
Unsafe.park()实现的平台差异问题。 - 调整Jetty线程池配置:检查QTP的
maxThreads、minThreads、idleTimeout等参数,若idleTimeout过短,可能导致空闲线程频繁切换状态,增加CPU消耗。 - 系统层面CPU热点采样:使用
perf top -p <PID>分析进程的内核态/用户态CPU分布,若内核态占比高,考虑升级Linux内核修复线程调度或锁竞争问题。 - 升级Jetty版本:排查当前Jetty版本是否存在
BlockingArrayQueue、QueuedThreadPool的已知bug,升级到最新稳定版验证问题是否解决。 - 监控系统资源瓶颈:用
vmstat、iostat、jstat工具检查CPU、内存、IO是否存在瓶颈,排除GC频繁、上下文切换过多等诱因。 - 跟踪线程状态变化:多次抓取
jstack转储,观察高CPU线程是否在WAITING和RUNNABLE间频繁切换,确认是否存在锁的高频竞争。 - 验证NUMA架构影响:若服务器启用NUMA,尝试在JVM启动参数中添加
-XX:+UseNUMA或-XX:-UseNUMA,排查线程调度异常问题。
内容的提问来源于stack exchange,提问作者Fabio Abreu
相关产品推荐
相关产品推荐

