web-dev-qa-db-ja.com

Spring @Scheduledにタイムゾーンを提供しますか?

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 属性があります。

38
matsev

@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
}
28
matsev

バージョン4.0以降、注釈@Scheduledに要素zoneがあります。

Java.util.TimeZoneで受け入れられる文字列としてタイムゾーンを挿入できます。

18
Vlasec

次のように、スプリングブートで@Scheduledタグでタイムゾーンを使用することもできます。

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

さまざまなジョブまたはアプリケーションの一部でさまざまなタイムゾーンを使用する必要があるとは思いません。すべてを一貫してDRYにしたい場合、すべてのサーバーのOSを一貫したタイムゾーンに設定するか、すべてのアプリケーションサーバーのuser.timezone Javaシステムプロパティを設定します。設定を集中管理します。 (OS、アプリケーションサーバー)、およびそのためには人形とシェフが非常に役立ちます。

0
Stevo Slavić

コードは次のようになります。

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

「ゾーン」は、希望する国のタイムゾーンになります。

これは、Springでのスケジュールされたタスクに関する素晴らしいチュートリアルです。

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

0
dmarquina