gpt4 book ai didi

c# - Quartz.NET - 计划任务停止随机运行

转载 作者:太空宇宙 更新时间:2023-11-03 20:03:02 25 4
gpt4 key购买 nike

我们按照从每 30 秒到每周一次的不同时间表为各种作业运行 Quartz.NET。

在查看我们的内部日志记录时,我们发现有些作业已无缘无故停止运行,而其他作业仍在继续运行。例如,我们的每 30 秒一次的作业在给定时间失败,而另一个每 10 分钟一次的作业持续了几个小时,然后也失败了。一个日常任务后来停止了。

我们启用了 Quartz 日志记录并发现了以下内容。

先前成功的火灾记录:

2014-09-19 08:20:00.0130 DEBUG Producing instance of Job 'DEFAULT.Scheduled task #5', class=TaskRunner
2014-09-19 08:20:00.0130 DEBUG Calling Execute on job DEFAULT.Scheduled task #5
2014-09-19 08:20:00.0130 DEBUG Batch acquisition of 1 triggers
2014-09-19 08:20:00.8710 DEBUG Trigger instruction : NoInstruction
2014-09-19 08:20:00.8710 DEBUG Batch acquisition of 1 triggers

第一次失败的日志:

2014-09-19 08:30:00.0046 DEBUG Producing instance of Job 'DEFAULT.Scheduled task #5', class=TaskRunner
2014-09-19 08:30:00.0046 DEBUG Calling Execute on job DEFAULT.Scheduled task #5
2014-09-19 08:30:00.0046 DEBUG Batch acquisition of 1 triggers

在此之后,在我们重新启动服务之前,这个特定的作业再也没有运行过。没有迹象表明我们的任何代码都在这个特定实例上运行,因为我们在内部进行自己的日志记录,这在当时并没有发生。

我们的 misfire 处理是为每个作业配置的,如下所示:

        ... TriggerBuilder.Create()
.WithCronSchedule( task.CronSchedule, x => x.WithMisfireHandlingInstructionDoNothing())
.Build();

我理解“DoNothing”指令告诉它跳过这场火灾并继续执行计划。因此,如果发生失火,我预计它会在下一次点火时再次点火。

1) 为什么我们的 Quartz 作业会随机失败?

2) 我们可以做些什么来进一步调查?

最佳答案

使用来源,卢克! quartz 是开源的。所以挖进去吧!

搜索该日志消息(“调用执行”)将我带到 JobRunShell.cs 中的这段代码(最新源代码):

// Execute the job
try
{
if (log.IsDebugEnabled)
{
log.Debug("Calling Execute on job " + jobDetail.Key);
}
job.Execute(jec);
endTime = SystemTime.UtcNow();
}
catch (JobExecutionException jee)
{
endTime = SystemTime.UtcNow();
jobExEx = jee;
log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key), jobExEx);
}
catch (Exception e)
{
endTime = SystemTime.UtcNow();
log.Error(string.Format(CultureInfo.InvariantCulture, "Job {0} threw an unhandled Exception: ", jobDetail.Key), e);
SchedulerException se = new SchedulerException("Job threw an unhandled exception.", e);
qs.NotifySchedulerListenersError(
string.Format(CultureInfo.InvariantCulture, "Job ({0} threw an exception.", jec.JobDetail.Key), se);
jobExEx = new JobExecutionException(se, false);
}
jec.JobRunTime = endTime - startTime;

// notify all job listeners
if (!NotifyJobListenersComplete(jec, jobExEx))
{
break;
}
instCode = SchedulerInstruction.NoInstruction;
// update the trigger
try
{
instCode = trigger.ExecutionComplete(jec, jobExEx);
if (log.IsDebugEnabled)
{
log.Debug(string.Format(CultureInfo.InvariantCulture, "Trigger instruction : {0}", instCode));
}
}
catch (Exception e)
{
// If this happens, there's a bug in the trigger...
SchedulerException se = new SchedulerException("Trigger threw an unhandled exception.", e);
qs.NotifySchedulerListenersError("Please report this error to the Quartz developers.", se);
}

因此,查看您的输出,我们在上面的代码示例中的第 6 行看到了日志消息。但是,我们从未看到触发器清理(倒数第三行)输出。

请注意,在该代码的每个 catch 语句中,我们都在创建调度程序异常并通知监听器?

好吧,选择很明确:在新建 Quartz 调度程序时向其添加一个新的 SchedulerListener(使用您自己的类实现 ISchedulerListener),然后监听调度程序异常,并记录错误. SchedulerException 包装了原始异常,因此您应该可以访问其中的底层错误。

顺便说一句...所有代码片段都在另一个 try block 中...但没有 catch block 。如果您仍然找不到发生了什么,那么在此函数上添加一个全局捕获并执行它们在文件其他位置执行的操作(将异常包装在 SchedulerException 中并通知监听器)。

关于c# - Quartz.NET - 计划任务停止随机运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26050874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com