为Spring @Scheduled提供时区



如何配置基于Spring的@Scheduled cron作业的时区?

背景:

我有一个工作,每天执行一次,比如下午2点,使用Spring的@Scheduled注释:

@Scheduled(cron = "0 0 14 * * *")
public void execute() {
    // do scheduled job
}

问题是2 PM在不同的服务器之间是不同的,因为Spring在内部使用TimeZone.getDefault()。此外,TimeZone.getDefault()的JavaDoc声明:

获取此主机的默认时区。默认TimeZone的来源可能因实现而异。

也就是说,没有确定时区。这可能取决于JVM实现、服务器时区配置、服务器位置和/或其他未知因素。因此,cron作业在不同的服务器上的不同时间触发,除非有一种方法可以显式地设置应该使用哪个时区。

我使用的是Spring 3.2.2.


在Spring 4中,Spring Jira问题SPR-10456已经解决。因此,@Scheduled注释有一个新的zone属性正好用于此目的。

事实证明,我不能使用@Scheduled注释,但我实现了一个解决方案。在SchedulingConfigurer的JavaDoc中声明:

[schedulingconfigrer]通常用于设置一个特定的TaskScheduler bean,以便在执行计划任务时使用,或者以编程的方式注册计划任务,而不是使用@Scheduled注释的声明性方法。

接下来,我更改了cron作业以实现Runnable接口,然后更新了我的配置文件以实现SchedulingConfigurer,见下面:

@Configuration
@EnableScheduling
@ComponentScan("package.that.contains.the.runnable.job.bean")
public class JobConfiguration implements SchedulingConfigurer {
    private static final String cronExpression = "0 0 14 * * *";
    private static final String timeZone = "CET";
    @Autowired
    private Runnable cronJob;
    @Bean
    CronTrigger cronTrigger() {
        return new CronTrigger(cronExpression, TimeZone.getTimeZone(timeZone));
    }
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addCronTask(new CronTask(job, cronTrigger()));
    }
}

请阅读@ enablesscheduling的JavaDoc以获取更多信息。


在Spring 4中,Spring Jira问题SPR-10456已经解决。因此,@Scheduled注释有一个新的zone属性,就是为了这个目的,例如

@Scheduled(cron = "0 0 14 * * *", zone = "CET")
public void execute() {
    // do scheduled job
}

从4.0版本开始,注释@Scheduled中有元素zone

您可以将时区作为java.util.TimeZone可以接受的字符串插入。

你的代码应该像这样:

@Scheduled(cron = "0 0 14 * * *", zone = "GMT-5")
    public void execute() {
     // do scheduled job
}

"Zone"将是所需国家的时区。

这是一个关于Spring计划任务的很好的教程:

https://www.baeldung.com/cron-expressions

您也可以像这样在spring-boot中使用@Scheduled标记的时区:

@Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
    // do the scheduled job
}

我怀疑您希望不同的工作或应用程序的一部分使用不同的时区。假设您想要保持一致和DRY,要么在所有服务器上配置操作系统使其具有一致的时区,要么设置user。所有应用服务器的timezone Java系统属性。集中管理配置(操作系统、应用服务器),因此puppet和chef非常有用。

相关内容

  • 没有找到相关文章

最新更新