Springベースの @ Scheduled cronジョブのタイムゾーンを構成するにはどうすればよいですか?
背景:
Springの_@Scheduled
_注釈を使用して、1日1回、たとえば午後2時に実行するジョブがあります。
_@Scheduled(cron = "0 0 14 * * *")
public void execute() {
// do scheduled job
}
_
問題は、SpringがTimeZone.getDefault()
内部 を使用するため、2 PMは異なるサーバー間で異なることです。さらに、 JavaDoc = of TimeZone.getDefault()
は次のことを述べています。
このホストのデフォルトのTimeZoneを取得します。デフォルトのTimeZoneのソースは、実装によって異なる場合があります。
つまり、タイムゾーンは決定されません。 JVMの実装、サーバーのタイムゾーン構成、サーバーの場所、および/またはその他の未知の要因に依存する場合があります。その結果、使用するタイムゾーンを明示的に設定する方法がない限り、cronジョブは異なるサーバーで異なる時間にトリガーされますか?
Spring 3.2.2を使用しています。
更新
Spring 4の時点で、Spring Jiraの問題 SPR-10456 は解決されました。したがって、_@Scheduled
_注釈には、まさにこの目的のために新しい zone 属性があります。
@Scheduled
注釈を使用できないことが判明しましたが、回避策を実装しました。 SchedulingConfigurer のJavaDocには、次のように記載されています。
[SchedulingConfigurer is]通常、スケジュールされたタスクを実行するときに使用される特定の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()));
}
}
詳細については、 @ EnableScheduling の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
タグでタイムゾーンを使用することもできます。
@Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
// do the scheduled job
}
さまざまなジョブまたはアプリケーションの一部でさまざまなタイムゾーンを使用する必要があるとは思いません。すべてを一貫してDRYにしたい場合、すべてのサーバーのOSを一貫したタイムゾーンに設定するか、すべてのアプリケーションサーバーのuser.timezone Javaシステムプロパティを設定します。設定を集中管理します。 (OS、アプリケーションサーバー)、およびそのためには人形とシェフが非常に役立ちます。
コードは次のようになります。
@Scheduled(cron = "0 0 14 * * *", zone = "GMT-5")
public void execute() {
// do scheduled job
}
「ゾーン」は、希望する国のタイムゾーンになります。
これは、Springでのスケジュールされたタスクに関する素晴らしいチュートリアルです。