繁体   English   中英

Spring Quartz计划任务在一段时间后停止运行

[英]Spring Quartz scheduled task stops running after some time

我有一个在Web应用程序中运行的Quartz计时器任务。 该任务每10秒检查数据库中特定表中的新数据。

<bean id="triggerCheckEvents" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
    <bean id="jobCheckEvents" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="checkEvents" />
        <property name="targetMethod" value="execute" />
        <property name="concurrent" value="false" />
    </bean>
</property>
<property name="startDelay" value="${checkEvent.startDelay}" />
<property name="repeatInterval" value="${checkEvent.repeatDelay}" />

大约每隔两天左右,计时器就会停止运行。 我可以肯定的是,它在数据库中执行某些操作时会卡住。 但是,重新启动数据库似乎对恢复计时器的正常功能没有影响。 没有异常被抛出。 因此没有堆栈跟踪。

当我试图找到根本原因时。 我认为,I / O问题注定会在长期运行的过程中发生。 因此,解决此问题的正确方法是拥有某种看门狗,例如,该看门狗将在超时后终止线程,生成新的胎面并按计划继续运行计时器。

当任务未能在指定的时间范围内返回时,是否可以终止计划的任务并创建新实例?

我不尝试使用数据库修复此特定错误。 因为明天其他错误可能会阻塞线程。 我正在寻找一个高级解决方案,该解决方案将终止进程或执行所需的任何操作以释放被挂起的计时器线程阻塞的资源并创建一个新实例。 长期运行中不可避免的问题是不可避免的。 正确的解决方案不是研究并解决出现的单个问题,而是制定一种即使出现错误也能恢复正常功能的策略。

我有一个类似的问题,其中一个任务曾经被阻塞。 一种方法是:在每次调用任务时,在新线程中进行实际操作,并使任务线程等待新线程完成(直到超过最大允许时间)。 这样,任务将永远不会被阻塞。

    public void work(JobExecutionContext ctx) {
    Thread t = new Thread(new Runnable() {
        public void run() {
            doSomethingInNewThread();
        }
    }, "ThreadName-" + System.currentTimeMillis());
    t.start();
    try {
        t.join(maxAllowedTime);
        if (t.isAlive()) {
            logger.warn("Tasks child thread "
                    + t.getName()
                    + "is still alive, potential thread block.");
            //TBD - if needed, add logic to terminate child thread
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM