简体   繁体   English

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

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

I have a Quartz timer task running in a webapp. 我有一个在Web应用程序中运行的Quartz计时器任务。 The task checks the database every 10 seconds for new data in a particular table. 该任务每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}" />

About every second day or so, the timer stops running. 大约每隔两天左右,计时器就会停止运行。 I am somewhat sure that it gets stuck while doing something in the database. 我可以肯定的是,它在数据库中执行某些操作时会卡住。 However, restarting the database does not seem to have effect on restoring the normal functioning of the timer. 但是,重新启动数据库似乎对恢复计时器的正常功能没有影响。 No exceptions get thrown. 没有异常被抛出。 So there is not stack trace. 因此没有堆栈跟踪。

While I am trying to find the root cause. 当我试图找到根本原因时。 I think, I/O problems are bound to occur in a long running process. 我认为,I / O问题注定会在长期运行的过程中发生。 So the proper solution to this problem is to have some kind of watchdog that would, say, kill the thread after a timeout, spawn a new tread and continue the timer as per schedule. 因此,解决此问题的正确方法是拥有某种看门狗,例如,该看门狗将在超时后终止线程,生成新的胎面并按计划继续运行计时器。

Is there a way to terminate a scheduled task and create a new instance when the task fails to return within a specified time frame? 当任务未能在指定的时间范围内返回时,是否可以终止计划的任务并创建新实例?

I am not trying to fix this particular error with the Database. 我不尝试使用数据库修复此特定错误。 Because tomorrow some other error may block the thread. 因为明天其他错误可能会阻塞线程。 I am looking for a high level solution that would just terminate the tread or do whatever is needed to free up resources blocked by the hung timer thread and create a fresh instance. 我正在寻找一个高级解决方案,该解决方案将终止进程或执行所需的任何操作以释放被挂起的计时器线程阻塞的资源并创建一个新实例。 Unexpected problems are inevitable in a long running process. 长期运行中不可避免的问题是不可避免的。 The right solution is not to study and fix numerous individual problems as and when they show up, but to have a strategy to restore normal function even when errors occur. 正确的解决方案不是研究并解决出现的单个问题,而是制定一种即使出现错误也能恢复正常功能的策略。

I had a similar problem where a task used to get blocked. 我有一个类似的问题,其中一个任务曾经被阻塞。 One approach is: at each invocation of the task, do actual stuff in new thread and make task's thread to wait for new thread to complete (till max allowed time is exceeded). 一种方法是:在每次调用任务时,在新线程中进行实际操作,并使任务线程等待新线程完成(直到超过最大允许时间)。 This way task will never get blocked. 这样,任务将永远不会被阻塞。

    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