56

Spring ベースの@Scheduled cron ジョブのタイムゾーンを設定するにはどうすればよいですか?

バックグラウンド:

@ScheduledSpring のアノテーションを使用して、1 日 1 回、たとえば午後 2 時に実行するジョブがあります。

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

TimeZone.getDefault() 問題は、Spring が内部的に on を使用するため、異なるサーバー間で 2 PM が異なることです。さらに、JavaDocには次のようにTimeZone.getDefault() 記載されています。

このホストのデフォルトの TimeZone を取得します。デフォルトの TimeZone のソースは、実装によって異なる場合があります。

つまり、時間帯は決まっていません。これは、JVM の実装、サーバーのタイム ゾーン構成、サーバーの場所、および / またはその他の未知の要因に依存する場合があります。その結果、使用するタイムゾーンを明示的に設定する方法がない限り、cron ジョブは異なるサーバーで異なる時間にトリガーされますか?

Spring 3.2.2 を使用しています。


アップデート

Spring 4 の時点で、Spring Jira の問題SPR-10456が解決されました。したがって、@Scheduledアノテーションにはまさにこの目的のための新しいゾーン属性があります。

4

5 に答える 5

43

アノテーションを使用できないことが判明しましたが、@Scheduled回避策を実装しました。SchedulingConfigurerの JavaDoc には、次のように記載されています。

[SchedulingConfigurer は] 通常、スケジュールされたタスクを実行するときに使用される特定の 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アノテーションにはまさにこの目的のための新しいゾーン属性があります。

@Scheduled(cron = "0 0 14 * * *", zone = "CET")
public void execute() {
    // do scheduled job
}
于 2013-04-13T15:04:21.263 に答える
22

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

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

于 2015-12-10T09:24:09.303 に答える
8

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

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

「ゾーン」は、目的の国のタイムゾーンになります。

Spring でスケジュールされたタスクに関する素晴らしいチュートリアルを次に示します。

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

于 2019-07-25T05:26:22.460 に答える
2

@Scheduled次のように、spring-boot でタグ付きのタイム ゾーンを使用することもできます。

@Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
    // do the scheduled job
}
于 2019-03-13T06:31:09.720 に答える
0

異なるジョブやアプリケーションの一部で異なるタイム ゾーンを使用する必要があるとは思えません。すべてを一貫性のある DRY にしたい場合は、すべてのサーバーで OS を構成してタイム ゾーンを統一するか、すべてのアプリケーション サーバーに user.timezone Java システム プロパティを設定します。構成 (OS、アプリケーション サーバー) を一元管理し、そのために puppet とchef は非常に便利です。

于 2013-04-14T09:48:20.377 に答える