The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

定期的なタスクのスケジューリング

モダンなアプリケーションでは、定期的に特定のタスクを実行する必要があります。このガイドでは、定期的なタスクのスケジュール方法を説明します。

クラスター化されたスケジューラーが必要な場合は、 Quartzエクステンション を使用してください。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

アーキテクチャ

このガイドでは、あるカウンタの現在値を取得するために HTTP を使用してアクセスできる簡単なアプリケーションを作成します。このカウンタは定期的に (10 秒ごとに) インクリメントされます。

アーキテクチャ

ソリューション

次のセクションの指示に従い、手順を追ってアプリを作成することをお勧めします。完成した例にそのまま進んでも構いません。

Git レポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitarchive をダウンロードします。

ソリューションは scheduler-quickstart ディレクトリ にあります。

Maven プロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します:

CLI
quarkus create app org.acme:scheduler-quickstart \
    --extension=resteasy-reactive,scheduler \
    --no-code
cd scheduler-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストール方法については、Quarkus CLIガイドをご参照ください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.11.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=scheduler-quickstart \
    -Dextensions="resteasy-reactive,scheduler" \
    -DnoCode
cd scheduler-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

これは以下の内容を含む新しいプロジェクトを生成します:

  • ランディングページは、http://localhost:8080 でアクセス可能です。

  • nativejvm の両方のモードに対応した Dockerfile ファイルのサンプル

  • アプリケーション設定ファイル

Maven プロジェクトは、RESTEasy Reactive と scheduler エクステンションもインポートします。

すでに Quarkus プロジェクトが設定されている場合は、プロジェクトのベースディレクトリーで以下のコマンドを実行することで、プロジェクトに scheduler エクステンションを追加することができます:

CLI
quarkus extension add 'scheduler'
Maven
./mvnw quarkus:add-extension -Dextensions="scheduler"
Gradle
./gradlew addExtension --extensions="scheduler"

これにより、 pom.xml に以下が追加されます:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-scheduler</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-scheduler")

スケジュールされたジョブの作成

org.acme.scheduler パッケージ に、以下の内容の CounterBean クラスを作成します:

package org.acme.scheduler;

import java.util.concurrent.atomic.AtomicInteger;
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.scheduler.Scheduled;
import io.quarkus.scheduler.ScheduledExecution;

@ApplicationScoped              (1)
public class CounterBean {

    private AtomicInteger counter = new AtomicInteger();

    public int get() {  (2)
        return counter.get();
    }

    @Scheduled(every="10s")     (3)
    void increment() {
        counter.incrementAndGet(); (4)
    }

    @Scheduled(cron="0 15 10 * * ?") (5)
    void cronJob(ScheduledExecution execution) {
        counter.incrementAndGet();
        System.out.println(execution.getScheduledFireTime());
    }

    @Scheduled(cron = "{cron.expr}") (6)
    void cronJobWithExpressionInConfig() {
       counter.incrementAndGet();
       System.out.println("Cron expression configured in application.properties");
    }
}
1 application スコープでの Bean の宣言
2 get() メソッドでは、現在の値を取得することができます。
3 @Scheduled アノテーションを使用して、ワーカースレッドが利用可能であれば 10 秒ごとにこのメソッドを実行するように Quarkus に指示します (Quarkus はスケジューラーに10個のワーカースレッドを使用しています)。ワーカースレッドが利用できない場合は、メソッドの呼び出しをデフォルトで再スケジューリングする必要があります。スケジュールされたメソッドの呼び出しは、前回の呼び出しのステータスや結果には依存しません。
4 コードはとても簡単です。10 秒ごとにカウンタがインクリメントされます。
5 cron のような式でジョブを定義します。アノテーションされたメソッドは毎日午前 10 時 15 分に実行されます。
6 application.properties で設定可能な cron.expr で cron のような式でジョブを定義します。

アプリケーション設定ファイルの更新

application.properties ファイルを編集し、 cron.expr の設定を追加します:

# By default, the syntax used for cron expressions is based on Quartz - https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
# You can change the syntax using the following property:
# quarkus.scheduler.cron-type=unix
cron.expr=*/5 * * * * ?

RESTリソースの作成

以下のように CountResource クラスを作成します:

package org.acme.scheduler;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/count")
public class CountResource {

    @Inject
    CounterBean counter;            (1)


    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "count: " + counter.get();  (2)
    }
}
1 CounterBean の注入
2 現在のカウンタの値の返却

アプリケーションのパッケージ化と実行

以下のコマンドでアプリケーションを実行します:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

別のターミナルで、curl localhost:8080/count を実行し、カウンタの値を確認します。 数秒後、curl localhost:8080/count を再実行し、カウンタが増分されたことを確認します。

コンソールを見て、 application.properties で設定された式を使って cron ジョブがトリガーされたことを示すメッセージ Cron expression configured in application.properties が表示されたことを確認します。

いつものように、アプリケーションは以下の方法でパッケージ化されます:

CLI
quarkus build
Maven
./mvnw clean package
Gradle
./gradlew build

そして、java -jar target/quarkus-app/quarkus-run.jar で実行されます。

以下のようにネイティブ実行可能ファイルを生成することもできます:

CLI
quarkus build --native
Maven
./mvnw package -Dnative
Gradle
./gradlew build -Dquarkus.package.type=native

スケジューラー設定リファレンス

ビルド時に固定される設定プロパティ - それ以外の設定プロパティは実行時に上書き可能

Configuration property

タイプ

デフォルト

The syntax used in CRON expressions.

Environment variable: QUARKUS_SCHEDULER_CRON_TYPE

cron4j, quartz, unix, spring

quartz

Scheduled task metrics will be enabled if a metrics extension is present and this value is true.

Environment variable: QUARKUS_SCHEDULER_METRICS_ENABLED

boolean

false

If schedulers are enabled.

Environment variable: QUARKUS_SCHEDULER_ENABLED

boolean

true

Scheduled task will be flagged as overdue if next execution time is exceeded by this period.

Environment variable: QUARKUS_SCHEDULER_OVERDUE_GRACE_PERIOD

Duration

1S

期間フォーマットについて

期間のフォーマットは標準の java.time.Duration フォーマットを使用します。詳細は Duration#parse() javadoc を参照してください。

数値で始まる期間の値を指定することもできます。この場合、値が数値のみで構成されている場合、コンバーターは値を秒として扱います。そうでない場合は、 PT が暗黙的に値の前に付加され、標準の java.time.Duration 形式が得られます。