1

我们在 64 位机器(集群,2 个实例,16GB 内存)上使用石英 2.1.5。我们在系统中有大约 8000 个触发器。

每秒我们有大约 50 个触发器——它们每秒都会被触发。

org.quartz.threadPool.threadCount = 50
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=100
org.quartz.scheduler.idleWaitTime=15000
#org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow=0 (this is not set)

Quartz 能够处理负载,但触发器会提前触发?

batchTriggerAcquisitionMaxCount - 我们可以将它增加到 500 并将 batchTriggerAcquisitionFireAheadTimeWindow 保持在 1000(1 秒),这些配置有什么缺点吗?

还有什么办法吗?

使用以下配置,它似乎工作正常。

org.quartz.threadPool.threadCount = 100
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=500
org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow=1000
org.quartz.scheduler.idleWaitTime=25000
4

1 回答 1

2

当石英想要运行您的触发器时,它会调用此方法:

triggers = qsRsrcs.getJobStore().acquireNextTriggers(now + idleWaitTime, Math.min(availThreadCount, qsRsrcs.getMaxBatchSize()), qsRsrcs.getBatchTimeWindow());

在哪里 :

  • idleWaitTimeorg.quartz.scheduler.idleWaitTime
  • availThreadCount是空闲线程的数量(将小于或等于org.quartz.threadPool.threadCount
  • qsRsrcs.getMaxBatchSize()org.quartz.scheduler.batchTriggerAcquisitionMaxCount
  • qsRsrcs.getBatchTimeWindow()org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow

它会导致如下 SQL 请求:

SELECT * FROM TRIGGERS WHERE NEXT_FIRE_TIME <= now + idleWaitTime + qsRsrcs.getBatchTimeWindow() LIMIT Math.min(availThreadCount, qsRsrcs.getMaxBatchSize())

所以是的,Quartz 总是提前运行触发器idleWaitTime + qsRsrcs.getBatchTimeWindow()。如果您将 getBatchTimeWindow 设置为零,idleWaitTime 设置为 1000(这是一个最小值),则需要的最小触发器数。在这种情况下,除了那些预期会运行的触发器之外,它仍然会采用应该提前 1 秒发生的触发器。

如果你想提前完全停止触发,你可以设置batchTriggerAcquisitionMaxCount为 1。这种情况下的缺点是你可以获得太多的 SQL 请求。您可以尝试使用batchTriggerAcquisitionMaxCount参数并找到最适合您的值。

BTW 查看 Quartz 代码,您可以看到将 batchTriggerAcquisitionMaxCount 设置为大于 threadCount 是没有意义的。

于 2013-06-07T15:43:55.590 回答