Tomcat下Java应用大量org.apache.openejb.pool.scheduler线程排查求助
关于Tomcat中大量org.apache.openejb.pool.scheduler线程的问题解答
问题描述
运行在Tomcat中的Java应用出现了数千个org.apache.openejb.pool.scheduler线程,目前暂未引发异常,但大量线程存在不符合预期,线程栈信息如下:
"org.apache.openejb.pool.scheduler.124" daemon prio=5 tid=2599 TIMED_WAITING at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#1320 Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#3514 at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) Local Variable: java.util.concurrent.locks.ReentrantLock#5616 Local Variable: java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#458 at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) Local Variable: java.util.concurrent.ScheduledThreadPoolExecutor#458 Local Variable: java.util.concurrent.ThreadPoolExecutor$Worker#457 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
线程来源
这些线程属于OpenEJB框架的对象池调度线程池,OpenEJB是一款嵌入式EJB容器。如果你的应用集成了OpenEJB(比如在Tomcat中引入OpenEJB组件,或依赖了包含OpenEJB的第三方包),就会启动该调度线程池,它的核心作用是维护对象池,包括定期清理闲置对象、校验对象状态等。
出现数千个线程的原因通常是:线程池配置不合理(默认参数被错误修改)、依赖版本存在线程泄漏bug,或是不必要的OpenEJB依赖未移除导致无意义的线程池扩容。
消除方法
- 移除不必要的OpenEJB依赖:如果应用不需要使用EJB功能,直接从项目依赖中删除OpenEJB相关包(如Maven的
openejb-core、openejb-tomcat,Gradle对应依赖),彻底终止该线程池的创建。 - 调整线程池配置参数:若必须保留OpenEJB,通过配置限制线程池大小:
- 在OpenEJB的配置文件(如
openejb.xml)中添加容器配置:<Container id="Default Stateless Container" type="STATELESS"> <Property name="scheduler.corePoolSize">5</Property> <Property name="scheduler.maxPoolSize">20</Property> </Container> - 或通过JVM启动参数设置:
-Dorg.apache.openejb.pool.scheduler.corePoolSize=5 -Dorg.apache.openejb.pool.scheduler.maxPoolSize=20
- 在OpenEJB的配置文件(如
- 升级兼容版本:检查OpenEJB与Tomcat的版本兼容性,部分旧版本OpenEJB在Tomcat环境下存在线程池泄漏问题,升级到稳定兼容版本可解决该问题。
- 排查代码中的不当使用:若应用中手动实例化了OpenEJB的对象池,检查是否存在未正确关闭线程池、重复创建线程池的情况,及时修正代码以复用或销毁线程池。
内容的提问来源于stack exchange,提问作者Mark1234
相关产品推荐
相关产品推荐

