0

假设我有像 0 0 12 1/1 * 这样的 Cron 表达式?* 由于某些原因,服务器在 11:50 到 12:05 之间停止,并且在这种情况下在 12:05 之后再次启动,一旦服务器启动,我如何触发错过的预定 Cron 表达式?石英是否有任何解决方案来处理上述问题。

4

2 回答 2

0

请参阅 Quartz 文档教程这篇精彩的文章“Misfire Instructions”,它们是 Quartz 触发器用于恢复错过的作业执行的策略。

如果你想容忍服务器关闭/崩溃,你需要配置 Quartz 使用持久的 Job Store 来像JDBCJobStore一样“记住”崩溃前的最后一个作业执行。

更新:请参阅解释如何创建可恢复作业的答案

于 2013-09-19T09:39:32.467 回答
0

我也遇到了想要在服务器重新启动时运行最后一个计划作业的问题。

我找到的解决方案是返回触发器的一个时间间隔并计算下一次触发时间。通过遍历所有触发器,可以确定触发器在过去应该触发的最近时间。


计算每次发射之间的间隔:

Date nextFireTime = trigger.getNextFireTime();
Date subsequentFireTime = trigger.getFireTimeAfter(nextFireTime);
long interval = subsequentFireTime.getTime() - nextFireTime.getTime();

查找下一次触发时间,直到过去的时间间隔:

Date previousPeriodTime = new Date(System.currentTimeMillis() - interval);
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime);

我发现如果您使用的是 aCronTrigger这可以防止您在过去要求开火时间。为了解决这个问题,我修改了开始时间,所以上面的代码片段变成了:

Date originalStartTime = trigger.getStartTime(); // save the start time
Date previousPeriodTime = new Date(originalStartTime.getTime() - interval);
trigger.setStartTime(previousPeriodTime);
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime);
trigger.setStartTime(originalStartTime); // reset the start time to be nice

遍历所有触发器并找到最近的触发器:

for (String groupName : scheduler.getTriggerGroupNames()) {
    for (String triggerName : scheduler.getTriggerNames(groupName)) {
        Trigger trigger = scheduler.getTrigger(triggerName, groupName);
        // code as detailed above...
        interval = ...
        previousFireTime = ...
    }
}

此代码可以重构为辅助方法或类。我实际上在一个子类委托触发器中使用了上述算法,然后我将其放入按先前触发时间排序的集合中。

于 2013-09-24T10:30:35.897 回答