Fournir le fuseau horaire à Spring @ Scheduled ?
Comment puis-je configurer le fuseau horaire pour un travail cron basé sur Spring @Scheduled?
Contexte:
J'ai un travail qui s'exécute une fois par jour, disons 14 heures, en utilisant L'annotation @Scheduled
de Spring:
@Scheduled(cron = "0 0 14 * * *")
public void execute() {
// do scheduled job
}
Le problème est que 2 PM diffère entre les différents serveurs, Car Spring utilise on TimeZone.getDefault()
en interne . De plus, le JavaDoc de TimeZone.getDefault()
indique que:
Obtient le fuseau horaire par défaut de cet hôte. La source de la valeur par défaut Le fuseau horaire peut varier avec l'implémentation.
En d'autres termes, le fuseau horaire n'est pas déterminé. Cela peut dépendre de l'implémentation de la JVM, de la configuration du fuseau horaire du serveur, de l'emplacement du serveur et / ou d'autres facteurs inconnus. Par conséquent, le travail cron se déclenche à des moments différents sur différents serveurs, à moins qu'il existe un moyen de définir explicitement quel fuseau horaire doit être utilisé?
J'utilise Spring 3.2.2.
Mise à Jour
À partir du printemps 4, printemps JIRA question SPR-10456 a été résolu. Par conséquent, l'annotation @Scheduled
a un nouvel attribut zone à cette fin.
3 réponses
Il S'est avéré que je ne pouvais pas utiliser l'annotation @Scheduled
, mais j'ai implémenté un contournement. Dans le JavaDoc du SchedulingConfigurer Il est indiqué que:
[SchedulingConfigurer est] généralement utilisé pour définir un bean TaskScheduler spécifique à utiliser lors de l'exécution de tâches planifiées ou pour enregistrer des tâches planifiées de manière programmatique, par opposition à l'approche déclarative de l'utilisation de l'annotation @Scheduled.
Ensuite, j'ai changé le travail cron en implémentez l'interface Runnable
, puis mettez à jour mon fichier de configuration pour implémenter le SchedulingConfigurer
, Voir ci-dessous:
@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()));
}
}
Veuillez lire le JavaDoc du @EnableScheduling pour plus d'informations.
Mise à Jour
Depuis le printemps 4, le problème Spring Jira SPR-10456 a été résolu. Par conséquent, l'annotation @Scheduled
a un nouvel attribut zone à cette fin.
Il y a l'élément zone
dans l'annotation @Scheduled
, à partir de la version 4.0.
Vous pouvez insérer un fuseau horaire comme une chaîne qui peut être acceptée par java.util.TimeZone
.
Je doute que vous souhaitiez que différents travaux ou parties d'application utilisent différents fuseaux horaires. En supposant que vous voulez que tout soit cohérent et sec, configurez le système d'exploitation sur tous les serveurs pour avoir un fuseau horaire cohérent ou définissez l'utilisateur.propriété système Java timezone pour tous les serveurs d'applications. Gérer centralement la configuration (OS, serveur d'applications), et pour cela puppet et chef peut être très utile.