【发布时间】:2017-02-14 22:03:44
【问题描述】:
因此,过去 2 周我们一直面临着一个问题。我们有一个在 3 个节点上运行的应用程序。 环境是:
Framework : Spring Boot on Tomcat
Runtime : JVM 1.8
OS : centOS 7
过去几周,所有节点的平均负载从0开始,在几个小时内逐渐增加到30。这一点,尽管我们每秒只收到大约 1-2 个请求。另外,Tomcat 部署在 8GB 4 核处理器上,CPU 利用率在 380-395% 之间波动。
我们分析了我们的应用程序并执行了线程转储。在我们的分析中,我们发现当平均负载>10时,可运行线程数保持在20左右,等待线程数在80左右。
这些等待线程的堆栈跟踪是:
sun.misc.Unsafe.park(Unsafe.java:-2) native
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(:-1)
java.util.concurrent.ThreadPoolExecutor.runWorker(:-1)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(:-1)
还应该指出,我们大量使用 Springs 的 @Async 注解。我们有一个 Executor,其线程池为 30 个线程。
如果我需要提供更多信息,请告诉我。我已经安装并使用 JProfiler 进行了分析,但仍然没有成功!
谢谢。
【问题讨论】:
-
20 个运行线程比您拥有的 4 个内核大得多。从 CPU 利用率来看,每个内核有 5 个线程正在做一些非常激烈的事情。您正在运行的线程的堆栈跟踪是什么?他们在做什么样的工作,任何繁重的计算,循环等?上下文切换的数量也会很有用。
标签: java linux multithreading tomcat concurrency