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