Java Quartz Scheduler突然停止运行并没有异常错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/618265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:01:52  来源:igfitidea点击:

Quartz Scheduler suddenly stop running and no exception error

javaquartz-scheduler

提问by

I have some quartz job which was running everyday at 7pm. Suddenly it failed to run. I check my server.log and there are no exception thrown. Anyone have any idea what could be the issue?

我有一些石英工作,每天晚上 7 点运行。突然就跑不动了。我检查了我的 server.log 并没有抛出异常。任何人都知道可能是什么问题?

Thanks in advance

提前致谢

回答by Jon Strayer

If you are using a database to store jobs, check the trigger_state of your trigger. Right now I'm seeing a similar problem (or at least it has similar symptoms).

如果您使用数据库来存储作业,请检查触发器的 trigger_state。现在我看到了类似的问题(或者至少它有类似的症状)。

A job that runs once a minute is leaving the trigger in "ACQUIRED" state and will never run again. Like you I'm seeing nothing the the log.

每分钟运行一次的作业使触发器处于“已获取”状态,并且永远不会再次运行。像你一样,我没有看到日志。

I'm also seeing a different cause of the same problem. Again, the job just stops running, but the trigger is not in the "ACQUIRED" state. So far I don't know the cause.

我也看到了相同问题的不同原因。同样,作业只是停止运行,但触发器未处于“已获取”状态。目前我还不知道原因。

What I know so far is that the scheduler thread is waiting for a free worker thread. It looks like all of the worker threads are waiting for a semaphore in order to update their schedule. I haven't been able to get a thread dump yet to verify what the worker threads are waiting on.

到目前为止我所知道的是调度程序线程正在等待一个空闲的工作线程。看起来所有的工作线程都在等待信号量以更新他们的计划。我还没有能够获得线程转储来验证工作线程正在等待什么。

I'm running Quartz 1.6.1 RC1. See this bug report: http://jira.opensymphony.com/browse/QUARTZ-668

我正在运行 Quartz 1.6.1 RC1。请参阅此错误报告:http: //jira.opensymphony.com/browse/QUARTZ-668

I think that's what I'm seeing.

我想这就是我所看到的。

回答by juanjo.arana

Check if any Job is throwing an Exception. Put your Job exe code in a try catch block an trace any exception to troubleshoot the problem.

检查是否有任何作业抛出异常。将您的 Job exe 代码放在 try catch 块中以跟踪任何异常以解决问题。

回答by Ahmed Othman

I had a similar problem but the problem was, I had 10 threads quartz default number of threads in quartz properties and when I made thread dump* I found that I have 10 jobs in blockedstat, which means that I can't run any more threads.

我有一个类似的问题,但问题是,我在石英属性中有 10 个线程石英默认线程数,当我进行线程转储时*我发现我在阻塞状态中有 10 个作业,这意味着我不能再运行了线程。

A quick fix to this problem to increase the number of threads in the thread pool in the quartz properties.

快速修复此问题以增加石英属性中线程池中的线程数。

The actual fix was reviewing my code to know why I had a 10 blocked threads.

实际的修复是查看我的代码以了解为什么我有 10 个阻塞的线程。

*to do thread dump you can use kill -3 < java process number >which print the thread dump to your application standard output i.e if you running tomcat you find it in catalina.outlog file

*要进行线程转储,您可以使用kill -3 < java 进程号 >将线程转储打印到您的应用程序标准输出,即如果您运行 tomcat,您可以在catalina.out日志文件中找到它

回答by venkaiah

I had similar but somewhat different problem. My scheduler is running fine in the development environment. In this scheduler I am doing the jobs like updating the transactions, etc.

我有类似但有些不同的问题。我的调度程序在开发环境中运行良好。在这个调度程序中,我正在做更新事务等工作。

When we move the build to production, the schedulers ran well and everything was fine until Saturday. On Saturday my scheduler was suddenly stopped. I didn't find any exception related to the scheduler in my app server (OC4J).

当我们将构建转移到生产中时,调度程序运行良好,直到星期六一切都很好。星期六,我的调度程序突然停止了。我在我的应用服务器 (OC4J) 中没有发现任何与调度程序相关的异常。

I am using quartz-1.5.2 version. I am unable to trace the actual root cause of the problem.

我使用的是quartz-1.5.2 版本。我无法追踪问题的实际根本原因。

I am starting the scheduler on startup of the application server. If something goes wrong then it stops working. Then I am not having any chance to start them.

我正在启动应用程序服务器时启动调度程序。如果出现问题,则它停止工作。那我就没有机会开始他们了。

I think if I start the schedulers by calling the init servlet using some jsp request again makes the difference. It will be like seeing the profile (health of our schedulers and starting them again). If you have any better approach to start the scheduler then please suggest me.

我想如果我通过再次使用一些 jsp 请求调用 init servlet 来启动调度程序会有所不同。这就像查看配置文件(我们的调度程序的健康状况并再次启动它们)。如果您有更好的方法来启动调度程序,请建议我。

回答by Luismi Lainez

In my case I had an open connection to the database. When the I had no more connections available, my threads remained waiting forever. As I could not start any other jobs, nothing happened and everything stayed blocked. My advice is for you to check if you have any blocking resource that you might need to release.

在我的情况下,我有一个到数据库的开放连接。当我没有更多可用连接时,我的线程永远等待。由于我无法开始任何其他工作,什么也没发生,一切都被阻止了。我的建议是让您检查是否有任何可能需要释放的阻塞资源。

回答by Panagiotis Drakatos

I had a similar problem and unfortunately, none of the above answers helped me to figure out my problem. I am using quartz-2.3.2 version. First of all, i agree with some others, wherein most of the cases the scheduler not fired up, is caused due to threads race conditions which blocked and try to acquire the flag from the thread entered the critical zone and it does not release it. This simply smells a kind of bad code but anyway, i don't want to say again the same thing like the others did.I want to come up with my solution to give you the way on which i fixed the problem.

我有一个类似的问题,不幸的是,上述答案都没有帮助我弄清楚我的问题。我使用的是quartz-2.3.2 版本。首先,我同意其他一些情况,其中大多数情况下调度程序没有启动,是由于线程竞争条件导致阻塞并尝试从进入临界区的线程获取标志并且它没有释放它。这只是闻到了一种糟糕的代码,但无论如何,我不想像其他人一样再说一遍。我想提出我的解决方案,为您提供解决问题的方法。

Assuming you use a Cron scheduler like the following way i will provide a detailed example

假设您像下面这样使用 Cron 调度程序,我将提供一个详细的示例

this is the SimpleJob class

这是 SimpleJob 类

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

public class SimpleJob implements Job {

    private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);

    public SimpleJob() {
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        // This job simply prints out its job name and the
        // date and time that it is running
        JobKey jobKey = context.getJobDetail().getKey();
        _log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
    }

}

This is your main class

这是你的主课

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

public class CronTriggerExample {

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(CronTriggerExample.class);

        log.info("------- Initializing -------------------");

        // First we must get a reference to a scheduler
        JobDetail job = newJob(SimpleJob.class)
                .withIdentity("job1", "group1").build();

        CronTrigger trigger = newTrigger()
            .withIdentity("trigger1", "group1")
            .withSchedule(cronSchedule("10 10/5 * ? * *").withMisfireHandlingInstructionFireAndProceed())
            .build();
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }

    public static void main(String[] args) throws Exception {

        CronTriggerExample example = new CronTriggerExample();
        example.run();
    }
}

The below cron expression means At second :10, every 5 minutes starting at minute :10, of every hour.

下面的 cron 表达式表示 At second :10,每 5 分钟从分钟 :10 开始,每小时。

cronSchedule("10 10/5 * ? * *")

If you notice the most interesting part here is the

如果你注意到这里最有趣的部分是

withMisfireHandlingInstructionFireAndProceed()

This is the key to solve your problem if your trigger is felt in a misfire situation, it instructs your scheduler to be fired immediately. An alternative occasion is to use

如果您的触发器在失火情况下被感觉到,这是解决您问题的关键,它会指示您的调度程序立即被触发。另一种情况是使用

withMisfireHandlingInstructionDoNothing()

where upon a mis-fire situation the cronTrigger will be next fired at the started time which the scheduler is set on. For example in our case in At second :10, every 5 minutes starting at minute :10, of every hour.

在发生错误触发的情况下,cronTrigger 将在调度程序设置的开始时间被触发。例如,在我们的例子中,At second :10,每 5 分钟从分钟 :10 开始,每小时一次。