所有Quartz Scheduler线程都转到TIMED_WAITING?

时间:2017-06-19 09:21:46

标签: java spring multithreading quartz-scheduler

我有Spring的Quartz作业(聚集)以定期间隔(1分钟)运行。当服务器启动时,一切似乎都很好,但一段时间后工作不会被触发。重新启动服务器会使作业运行,但会在一段时间后重新发生。

我怀疑这是一个线程耗尽问题,并且从线程转储中我注意到我的所有Quartz线程(10)都在TIMED_WAITING中。

配置:

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

线程转储:

quartzScheduler_Worker-10 - priority:10 - threadId:0x00007f8ae534d800 - nativeId:0x13c78 - state:TIMED_WAITING stackTrace:
    java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000066cd73220> (a java.lang.Object)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
        - locked <0x000000066cd73220> (a java.lang.Object)

使用 quartz 2.2.1 (我怀疑它是否可能是版本特定的问题)

我从日志中验证了没有数据库连接问题。

请帮助诊断问题。我是否有可能超出系统资源(线程数)?但是我的作业是同步的,只有当它的所有子线程都完成了它们的任务时才存在,并且我也有这个注释 @DisallowConcurrentExecution

1 个答案:

答案 0 :(得分:0)

根本原因是我们的石英工作中有太多未命中的火灾。我们每1分钟就有一次石英踢,并且工作在1分钟内没有完成,所以它会因为小火和石英试图先执行它们而被填满。

在这个过程中,有一次更新未命中火的操作,这需要花费大量时间导致石英卡住。从线程转储中可以看出这一点,我们所有的石英线都处于TIMED_WAITING状态,如下所示

quartzScheduler_Worker-10 - priority:10 - threadId:0x00007f8ae534d800 - nativeId:0x13c78 - state:TIMED_WAITING
stackTrace:
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000066cd73220> (a java.lang.Object)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
- locked <0x000000066cd73220> (a java.lang.Object)

参考:https://jira.terracotta.org/jira/si/jira.issueviews:issue-html/QTZ-357/QTZ-357.html

对于我们的用例,可以忽略未命中的火灾,并可以在下次运行时选择。因此我将Misfire指令改为忽略,如下所示

<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY" />