Предоставить часовой пояс для Spring @Scheduled?

Как настроить часовой пояс для задания cron на основе Spring @Scheduled?

Фон:

У меня есть работа, которая выполняется один раз в день, например, в 2 часа дня, используя Spring @Scheduled аннотация:

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

Проблема в том, что 2 вечера отличаются между разными серверами, потому что Spring использует на TimeZone.getDefault() внутренне. Кроме того, JavaDoc TimeZone.getDefault() говорится, что:

Получает часовой пояс по умолчанию для этого хоста. Источник TimeZone по умолчанию может отличаться в зависимости от реализации.

Другими словами, часовой пояс не определяется. Это может зависеть от реализации JVM, конфигурации часового пояса сервера, расположения сервера и / или других неизвестных факторов. Следовательно, задание cron запускается в разное время на разных серверах, если нет способа явно указать, какой часовой пояс следует использовать?

Я использую Spring 3.2.2.


Обновить

По состоянию на весну 4 проблема Spring Jira SPR-10456 была решена. Следовательно, @Scheduled аннотация имеет новый атрибут зоны именно для этой цели.

3 ответа

Решение

Оказалось, что я не мог использовать @Scheduled аннотации, но я реализовал обходной путь. В JavaDoc SchedulingConfigurer указано, что:

[SchedulingConfigurer is] Обычно используется для установки определенного компонента TaskScheduler, который будет использоваться при выполнении запланированных задач или для регистрации запланированных задач программным способом, в отличие от декларативного подхода с использованием аннотации @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()));
    }
}

Пожалуйста, прочитайте JavaDoc @EnableScheduling для получения дополнительной информации.


Обновить

По состоянию на весну 4 проблема Spring Jira SPR-10456 была решена. Следовательно, @Scheduled аннотация имеет новый атрибут зоны именно для этой цели.

Есть элемент zone в аннотации @Scheduled, начиная с версии 4.0.

Вы можете вставить часовой пояс в виде строки, которая может быть принята java.util.TimeZone,

Ваш код должен быть таким:

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

"Зона" станет часовым поясом желаемой страны.

Вот хороший урок о запланированных задачах с Spring:

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

Вы также можете использовать часовой пояс с @Scheduled тег в весенней загрузке вот так:

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

Я сомневаюсь, что вы хотите, чтобы разные задания или части приложения использовали разные часовые пояса. Предполагая, что вы хотите, чтобы все было согласованным и СУХИМЫМ, либо настройте ОС на всех серверах, чтобы иметь согласованный часовой пояс, либо задайте системное свойство Java user.timezone для всех серверов приложений. Централизованно управляйте конфигурацией (ОС, сервер приложений), и для этого кукла и шеф-повар могут быть очень полезны.

Другие вопросы по тегам