Предоставить часовой пояс для 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:
Вы также можете использовать часовой пояс с @Scheduled
тег в весенней загрузке вот так:
@Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
// do the scheduled job
}
Я сомневаюсь, что вы хотите, чтобы разные задания или части приложения использовали разные часовые пояса. Предполагая, что вы хотите, чтобы все было согласованным и СУХИМЫМ, либо настройте ОС на всех серверах, чтобы иметь согласованный часовой пояс, либо задайте системное свойство Java user.timezone для всех серверов приложений. Централизованно управляйте конфигурацией (ОС, сервер приложений), и для этого кукла и шеф-повар могут быть очень полезны.