【问题标题】:Quartz: Debug undesired multiple job runsQuartz:调试不需要的多个作业运行
【发布时间】:2015-01-26 21:18:07
【问题描述】:

作业正在 Application_Start() 处安排:

var y= JobBuilder.Create<YY>()
            .WithIdentity("YY")
            .Build();

ITrigger z= TriggerBuilder.Create()
            .WithDescription("Runs.")
            .WithDailyTimeIntervalSchedule(x => x
            .WithIntervalInHours(24)
            .OnEveryDay()
            .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(9, 30))
            .InTimeZone(TimeZoneInfo.Utc))
            .Build();

Scheduler.ScheduleJob(y, z);

在工作中,我在开始时记录“工作开始”。 该作业在过去几天正常运行,但从过去 2 天开始,我可以在日志中看到“作业开始”出现 3 次,相差几毫秒。添加到作业中的通知邮件程序也会发生同样的情况。

我怀疑这是由于指令失灵,但是否有任何调试和确定问题原因的方法,以及确保仅执行 1 个作业实例。

此作业需要 1-1.5 小时才能执行,并且可能在作业触发时发生了服务器重新启动和部署。这可能会影响触发场景。

【问题讨论】:

  • 我认为实际发生的情况是该特定代码在短时间内连续运行了多次。我认为这不是石英问题。触发此代码的代码更有可能运行多次。您使用的是哪个版本的 Quartz?
  • Quartz 版本是 2.2.2 由于调度程序驻留在 Application_Start() 中,我不太确定它是否可以运行多次。还有其他作业(运行时间不长)以相同的方式安排并且运行良好。
  • 好吧,我遇到了这样的问题,这是由于复制粘贴造成的,当我们添加新作业时,我们复制了现有的作业定义块并更改了除触发作业之外的所有内容,因此新触发器正在开始现有的工作。确保您的问题不是这样的!

标签: c# quartz-scheduler jobs quartz.net


【解决方案1】:

这样定义你的工作:

[DisallowConcurrentExecution]
public class YourJobClass : IJob
{
    //  Your Code...
}

[DisallowConcurrentExecution] 属性确保在任何时候最多有一个作业实例。

这只是一个猜测,但如果您的问题是由失火引起的,以下代码可能会有所帮助:

您可以使用以下代码更改调度程序的属性:

IScheduler scheduler;        
ISchedulerFactory schedulerFactory;
NameValueCollection propColl = new NameValueCollection();

propColl.Add("org.quartz.jobStore.misfireThreshold", "216000000");  // Amount of milliseconds that may pass till a trigger that couldn't start in time counts as misfired (216000000 ms => 1 hour) 
propColl.Add("org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow", "5"); // Trigger may fire up to 5 ms before scheduled starttime
propColl.Add("quartz.threadPool.threadCount", "1"); // Allows only one Thread in parallel
schedulerFactory = new StdSchedulerFactory(propColl);
scheduler = schedulerFactory.GetScheduler();
scheduler.Start();

至于你关于调试这个问题的问题:我个人只知道试错法。改变一点,看看会发生什么。

【讨论】:

    【解决方案2】:

    虽然它不能直接解决多个作业同时运行的问题,但有一些方法可以防止或至少缓解多个作业同时运行。

    Scheduler 有一个方法checkExists(),它可以接受一个jobKey 或一个triggerKey,如果job 或触发器已经存在则返回true。

    请注意,由于这些作业相距很近,可能存在竞争条件,在极少数情况下仍会导致双重作业执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      相关资源
      最近更新 更多