Java Quartz调度程序工作线程不运行作业,即使队列中有大量作业

Java Quartz调度程序工作线程不运行作业,即使队列中有大量作业,java,quartz-scheduler,Java,Quartz Scheduler,quartz scheduler中有30个工作线程,队列中有104k个作业(由于quartz处理速度不够快,提交了大量批量作业,所以这些作业堆积在一起)。正如您在线程转储中所看到的,这些线程中的大多数只是等待而没有工作。为什么这些工作线程没有运行队列中错过启动时间的所有作业 在将工作分配给工人之前,会有任何瓶颈吗?我们在任何时候都只能看到几个作业在运行,而不是一次最多运行30个作业 我应该注意到,这种情况的发生与只有一个或多个调度程序进程无关 如果能找到为什么很多(最多30个)工作没有被立即接受

quartz scheduler中有30个工作线程,队列中有104k个作业(由于quartz处理速度不够快,提交了大量批量作业,所以这些作业堆积在一起)。正如您在线程转储中所看到的,这些线程中的大多数只是等待而没有工作。为什么这些工作线程没有运行队列中错过启动时间的所有作业

在将工作分配给工人之前,会有任何瓶颈吗?我们在任何时候都只能看到几个作业在运行,而不是一次最多运行30个作业

我应该注意到,这种情况的发生与只有一个或多个调度程序进程无关

如果能找到为什么很多(最多30个)工作没有被立即接受和执行的原因,我们将不胜感激

Quartz版本:2.1.3(带有Oracle JDBC jobstore)

配置文件

#============================================================================
# Configure Main Scheduler Properties
#============================================================================

org.quartz.scheduler.instanceName = ****_SCHEDULER
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 30
org.quartz.threadPool.threadPriority = 5


#============================================================================
# Configure JobStore
#============================================================================

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.tablePrefix = QRTZ_


#============================================================================
# Configure Datasources
#============================================================================

org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@*****
org.quartz.dataSource.myDS.user = *****
#org.quartz.dataSource.myDS.password = *****
org.quartz.dataSource.myDS.maxConnections = 10
org.quartz.dataSource.myDS.validationQuery=select 0 from dual

#============================================================================
# Configured to batch trigger acquisition
#============================================================================
org.quartz.scheduler.skipUpdateCheck = false
org.quartz.scheduler.batchTriggerAcquisitionMaxCount = 30
org.quartz.jobStore.acquireTriggersWithinLock = true
~
线程转储

我看到QuartzSchedulerThread(我假设它像manager线程?)和MisfireHandler线程总是使用相同的堆栈跟踪运行(除了锁定的监视器id)

QuartzSchedulerThread的堆栈跟踪

at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:129) 
at oracle.net.ns.Packet.receive(Packet.java:300) 
at oracle.net.ns.DataPacket.receive(DataPacket.java:106) 
at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:260) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:185) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:102) 
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124) 
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) 
at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) 
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) 
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) 
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) 
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044) 
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1199) 
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289) 
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584) 
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628) 
- locked [0x00000007f5d0fd30] (a oracle.jdbc.driver.T4CConnection) 
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493) 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 
at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:91) 
at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:115) 
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3803) 
at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggersFired(JobStoreSupport.java:2893) 
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:326)
故障处理程序线程的堆栈跟踪:

位于java.net.SocketInputStream.socketRead0(本机方法)
位于java.net.SocketInputStream.read(SocketInputStream.java:129)
位于oracle.net.ns.Packet.receive(Packet.java:300)
位于oracle.net.ns.DataPacket.receive(DataPacket.java:106)
位于oracle.net.ns.NetInputStream.getNextPackage(NetInputStream.java:315)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
位于oracle.jdbc.driver.T4CSocketInputStreamWrapper.readnextPackage(T4CSocketInputStreamWrapper.java:124)
位于oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
位于oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
位于oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
位于oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
位于oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
位于oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
位于oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
在oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1199)
在oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289)中
位于oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
位于oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628)
-已锁定[0x00000007f58c8010](一个oracle.jdbc.driver.T4CConnection)
位于oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493)
在com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
位于org.quartz.impl.jdbjobstore.StdJDBCDelegate.hasmissiredtriggersinstate(StdJDBCDelegate.java:379)
位于org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:946)
位于org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoVerisFires(JobStoreSupport.java:3187)
位于org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:3946)
位于org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:3967)

我对Quartz scheduler了解不多,但作业是如何提交到池中的?调度程序线程是否可能是分发任务的线程,但它当前被锁定在IO(
java.net.SocketInputStream.socketRead0
)上,因此无法告诉工作人员该做什么?作业由另一个java进程提交,该进程只提交作业,不执行作业。有可能SchedulerRead在IO上很忙(读取作业?),并且没有像您所说的那样分发作业。我不知道如何找出瓶颈到底是什么。我无法在本地复制它,线程转储也没有多大帮助(你介意分享一些代码吗?Quartz是如何设置的?在Tomcat内部?作为一个独立的?另外,在30个线程中,你有没有可能超过服务器/主机的容量?可能会减少到10个线程,并推送30个作业通过,并监视线程转储,以查看它们是否通过处理。最后,你使用的Quartz版本是什么?我一直在正在处理一个涉及Quartz 1.8.6的Spring/Tomcat/Quartz相关问题,该问题冻结了Tomcat。@wildnux感谢您的回复!在我的案例中,最后我们在Oracle 11中发现了一个错误,该错误使一个select查询永久挂起而不超时。因此,线程处于活动状态,等待查询结果而不做任何其他操作。因此结束这根本不是Quartz的问题。我对Quartz scheduler了解不多,但作业是如何提交到池的?是否有可能是scheduler线程将任务分发到池中,但它当前锁定在IO上(
java.net.SocketInputStream.socketRead0
)因此无法告诉工人做什么?作业是由不同的java进程提交的,该进程只提交作业而不执行作业。可能SchedulerRead在IO上忙(读取作业?)而且没有像你说的那样分发它们。我不知道如何找出瓶颈到底是什么。我无法在本地复制它,线程转储也帮不了什么忙(你介意分享一些代码吗?Quartz是如何设置的?在Tomcat内部?作为一个独立的?另外,在30个线程中,你有没有可能超过服务器/主机的容量?可能会减少到10个线程,并推送30个作业通过,并监视线程转储,以查看它们是否通过处理。最后,你使用的Quartz版本是什么?我一直在处理与Spring/Tomcat/Quartz相关的问题