Spring 计划的 Cron 作业在错误的时间触发
Spring Scheduled Cron jobs firing at wrong time
我有一个 Spring 启动应用程序,其中包含使用 @Scheduled 注释的各种调度程序。一些计划使用 fixedRate 设置,其他使用 cron。 fixedRate 计划 运行 很好,但我注意到在过去的一个月里,cron 计划触发的实际时间每天会有 1-2 小时的变化。
即cron 设置为
的作业
@Scheduled(cron = "0 0 2 * * *")
将在 3:00 上午而不是 2:00 上午开火。它也不是每天都在发生。它会连续几天同时 运行,然后发生某些事情,每次 运行 都会关闭一个小时,直到我重新启动应用程序。
服务器上的系统时间是准确的,我完全没有想法。有人遇到过这个吗?
编辑 1
我输入了一些日志记录以确定作业是否在同一时间间隔内错误触发,结果似乎是随机的。以下是三天内上述 cron 作业的 start/end 次:
Format: Calendar.getInstance().getTime() (System.currentTimeMillis())
Start: Sat Oct 21 03:14:15 CDT 2017 (1508573655778)
End: Sat Oct 21 03:22:24 CDT 2017 (1508574144708)
Start: Sun Oct 22 02:26:58 CDT 2017 (1508657218774)
End: Sun Oct 22 02:35:12 CDT 2017 (1508657712492)
Start: Mon Oct 23 02:00:03 CDT 2017 (1508742003072)
End: Mon Oct 23 02:08:11 CDT 2017 (1508742491493)
它是每次都精确地关闭 1 小时,还是像您提到的那样可变?
您如何测量它触发的时间——使用日志记录?您注释的方法需要多长时间 运行?在方法的开头和结尾记录一条消息并比较这些时间戳。您可以尝试使用
private static final String CRON_SCHEDULE = "0 0 2 * * ?";
private static final String USER_TIMEZONE = "America/New_York";
// ...
@Scheduled(cron = CRON_SCHEDULE, zone = USER_TIMEZONE)
/* your method here */
查看指定时区时结果是否有任何不同。
终于想通了。我没有 ThreadPoolTaskScheduler 设置,所以我没有为 运行 所有计划的作业预留足够大的线程池。
@Configuration
public class TaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(30);
return threadPoolTaskScheduler;
}
}
我有一个 Spring 启动应用程序,其中包含使用 @Scheduled 注释的各种调度程序。一些计划使用 fixedRate 设置,其他使用 cron。 fixedRate 计划 运行 很好,但我注意到在过去的一个月里,cron 计划触发的实际时间每天会有 1-2 小时的变化。
即cron 设置为
的作业@Scheduled(cron = "0 0 2 * * *")
将在 3:00 上午而不是 2:00 上午开火。它也不是每天都在发生。它会连续几天同时 运行,然后发生某些事情,每次 运行 都会关闭一个小时,直到我重新启动应用程序。
服务器上的系统时间是准确的,我完全没有想法。有人遇到过这个吗?
编辑 1
我输入了一些日志记录以确定作业是否在同一时间间隔内错误触发,结果似乎是随机的。以下是三天内上述 cron 作业的 start/end 次:
Format: Calendar.getInstance().getTime() (System.currentTimeMillis())
Start: Sat Oct 21 03:14:15 CDT 2017 (1508573655778)
End: Sat Oct 21 03:22:24 CDT 2017 (1508574144708)
Start: Sun Oct 22 02:26:58 CDT 2017 (1508657218774)
End: Sun Oct 22 02:35:12 CDT 2017 (1508657712492)
Start: Mon Oct 23 02:00:03 CDT 2017 (1508742003072)
End: Mon Oct 23 02:08:11 CDT 2017 (1508742491493)
它是每次都精确地关闭 1 小时,还是像您提到的那样可变? 您如何测量它触发的时间——使用日志记录?您注释的方法需要多长时间 运行?在方法的开头和结尾记录一条消息并比较这些时间戳。您可以尝试使用
private static final String CRON_SCHEDULE = "0 0 2 * * ?";
private static final String USER_TIMEZONE = "America/New_York";
// ...
@Scheduled(cron = CRON_SCHEDULE, zone = USER_TIMEZONE)
/* your method here */
查看指定时区时结果是否有任何不同。
终于想通了。我没有 ThreadPoolTaskScheduler 设置,所以我没有为 运行 所有计划的作业预留足够大的线程池。
@Configuration
public class TaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(30);
return threadPoolTaskScheduler;
}
}