当前位置: 首页 > 知识库问答 >
问题:

Spring的@Scheduled cron作业在预定时间前几毫秒触发

麹正业
2023-03-14

我已经设置了Spring的@Sched的,每小时有一个cron表达式,如下所示,其中trend.olap.local.loading.cron.expression0 0 * * * ?.

@Scheduled(cron = "${trend.olap.local.loading.cron.expression}")
public void loadHoulyDataToLocalOlap() {
    try {
        // To calculate prev hour;
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR, -1);
        Date date = cal.getTime();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Loading hourly data into local olap :" + date
                    + ", and hour :" + hour);
        }

        dataIntegrationProcessor.loadHourlyDataToLocalOlap(hour);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Loading hourly data into local olap :" + date
                    + ", and hour :" + hour + " Completed.");
        }
    } catch (Exception e) {
        LOGGER.error("Error occured at loadHoulyDataToLocalOlap", e);
    }
}

这里我的目的是从当前日期和时间中获取小时值,并将其传递给executor方法。

基本上,我取当前小时减去1,所以在17:00,小时值应该是16。

但是如果你看到日志,小时值是15。这是因为调度程序运行16:59:59,831左右。请参阅下面的log4j日志。看起来cron作业正在舍入毫秒,并在17:00:00,000前几毫秒被触发。

正因为如此,我得到了错误的价值观,我的商业案例正在失败。

我如何让cron每小时都精确地运行在第0毫秒,而不是之前的几毫秒?

DEBUG 2013-09-29 16:59:59,831 (TrendScheduler.java loadHoulyDataToLocalOlap:57) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15
DEBUG 2013-09-29 16:59:59,831 (DataIntegrationProcessor.java loadHourlyDataToLocalOlap:57) - Loading hourly data for hour :15
INFO 2013-09-29 17:00:00,054 (KettleJobExecutor.java executeJob:73) - Job (24hr_populate_hour_data_job.kjb) executed successfully
DEBUG 2013-09-29 17:00:00,054 (TrendScheduler.java loadHoulyDataToLocalOlap:64) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15 Completed.

共有3个答案

陆宏壮
2023-03-14

Cron将忽略毫秒,这意味着它的准确度只能在一秒钟之内,前提是不存在任何其他计时问题,比如系统上的突然负载。

你有两个选择:1。在2小时后几秒钟开始cron作业。更改工时计算,以便提前触发作业。

在这两者中,第一个是最简单的,我不会说它比使用浮点数时允许舍入问题更疯狂。

郝君博
2023-03-14

如果你的意图是插入正确的小时值,我认为更好的解决方案是根据不太可预测的cron时间表计算小时。只要它在一秒钟内,您可以简单地获取当前时间并将其转换为最近的小时,然后从那里导出小时值。您还可以添加警告/警报,让您知道cron是否通过监听晚开始一分钟以上或晚开始10分钟等任务而表现不稳定。

虽然您可以调整cron计划,但我觉得这更像是一种黑客行为,而不是在代码中处理它,因为此时您正在逼近一个近似值。您在代码中有更多的控制权来处理超过100毫秒的偏移

岳劲
2023-03-14

简而言之,您不能使用cron选项。cron表达式的分辨率是秒,所以它会舍入到最近的秒。你可以保证它至少在特定的时间之后发生,但不完全是在cron上。

最好的选择是实现自己的触发器Trigger接口有一个方法返回java。util。下一次执行的日期(以毫秒为单位)。从那里,您可以注册任务和触发器,如以下文档所示:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableScheduling.html

 类似资料:
  • 本文向大家介绍js获取指定时间的前几秒,包括了js获取指定时间的前几秒的使用技巧和注意事项,需要的朋友参考一下 最近项目上有一个需求是:根据一张图片的拍摄时间获取到这个时间前二后三的一个五秒钟的视频信息,通过查找相关资料写了一个方法拿来记录分享一下。 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!

  • 我试图在应用程序启动10分钟后生成警报。根据我的要求,无论用户关闭应用程序、关闭并再次打开,或者甚至在重新启动后,此警报都应该工作。下面是我的代码。 主要活动。Java语言 我的服务。java—这是服务类。 警报eciever.java 如果我没有关掉手机或重新启动手机,我就可以准时收到闹钟。我准时收到闹钟。 然而,如果我关闭并打开手机,或者如果我重新启动手机,我会在手机打开/重新启动后立即收到警

  • 我希望能够用REST控制器开始我的作业,然后当作业开始时,它应该在计划的基础上运行,直到我用REST再次停止它。

  • 我从GPS接收机接收到一个时间戳,它以秒后的微秒时间表示:

  • 问题内容: 在我可以设置例如 是否有任何符号(%something)以毫秒为单位返回当前时间? 问题答案: 没有完全符合您需要的Log4J符号。 以给定的模式返回当前日期,该模式由(放在方括号之间的模式)定义,但是没有给您以毫秒为单位的时间。 给出自 执行开始以来的 毫秒数。 实现所需目标的一种可能方法是扩展Log4j的行为,这要复杂得多,但是如果绝对必要,请按以下步骤进行: 自定义log4j(编

  • 问题内容: 这是我的代码: 是否可以在日期格式中添加毫秒和纳秒? 问题答案: 您可以通过在末尾添加来添加毫秒数,例如格式为。 毫微秒内没有参考。通常用于性能调试,而不用于显示目的。