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

安排周期性任务

现代应用程序经常需要定期运行特定的任务。在本指南中,你将学习如何安排定期任务。

If you need a clustered scheduler use the Quartz extension.

先决条件

要完成这个指南,你需要:

  • 大概15分钟

  • 编辑器

  • 安装JDK 11以上版本并正确配置了 JAVA_HOME

  • Apache Maven 3.8.6

  • 如果你愿意的话,还可以选择使用Quarkus CLI

  • 如果你想构建原生可执行程序,可以选择安装Mandrel或者GraalVM,并正确配置(或者使用Docker在容器中进行构建)

应用结构

In this guide, we create a straightforward application accessible using HTTP to get the current value of a counter. This counter is periodically (every 10 seconds) incremented.

Architecture

解决方案

我们建议您按照下一节的说明逐步创建应用程序。然而,您可以直接转到已完成的示例。

克隆 Git 仓库: git clone https://github.com/quarkusio/quarkus-quickstarts.git ,或下载一个 存档

The solution is located in the scheduler-quickstart directory.

创建Maven项目

首先,我们需要一个新的项目。使用以下命令创建一个新的项目:

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

创建Grade项目,请添加 --gradle 或者 --gradle-kotlin-dsl 参数。

关于如何安装并使用Quarkus CLI的更多信息,请参考Quarkus CLI指南

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

创建Grade项目,请添加 -DbuildTool=gradle 或者 -DbuildTool=gradle-kotlin-dsl 参数。

It generates a new project including:

  • a landing page accessible on http://localhost:8080

  • example Dockerfile files for both native and jvm modes

  • 应用程序的配置文件

The project also imports the RESTEasy Reactive and scheduler extensions.

If you already have your Quarkus project configured, you can add the scheduler extension to your project by running the following command in your project base directory:

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

这将在您的构建文件中添加以下内容:

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

创建一个计划作业

In the org.acme.scheduler package, create the CounterBean class, with the following content:

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 Declare the bean in the application scope
2 get() 方法允许检索当前值。
3 Use the @Scheduled annotation to instruct Quarkus to run this method every 10 seconds provided a worker thread is available (Quarkus is using 10 worker threads for the scheduler). If it is not available the method invocation should be re-scheduled by default i.e. it should be invoked as soon as possible. The invocation of the scheduled method does not depend on the status or result of the previous invocation.
4 The code is pretty straightforward. Every 10 seconds, the counter is incremented.
5 Define a job with a cron-like expression. The annotated method is executed at 10:15am every day.
6 application.properties 中使用类似于cron表达式的方式定义一个名为 cron.expr 的作业。

更新该应用程序的配置文件

Edit the application.properties file and add the cron.expr configuration:

# 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 * * * * ?

Creating the REST resource

Create the CountResource class as follows:

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 ,以验证计数器已被递增。

Observe the console to verify that the message Cron expression configured in application.properties has been displayed indicating that the cron job using an expression configured in application.properties has been triggered.

像往常一样,该应用程序能够使用以下方式进行打包:

CLI
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

And executed with java -jar target/quarkus-app/quarkus-run.jar.

你也可以通过以下命令生成本地可执行文件:

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

Scheduler Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

类型

默认

The syntax used in CRON expressions.

Environment variable: QUARKUS_SCHEDULER_CRON_TYPE

Show more

cron4j, quartz, unix, spring, spring53

quartz

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

Environment variable: QUARKUS_SCHEDULER_METRICS_ENABLED

Show more

boolean

false

Tracing will be enabled if the OpenTelemetry extension is present and this value is true.

Environment variable: QUARKUS_SCHEDULER_TRACING_ENABLED

Show more

boolean

false

If schedulers are enabled.

Environment variable: QUARKUS_SCHEDULER_ENABLED

Show more

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

Show more

Duration

1S

About the Duration format

持续时间的格式使用标准的 java.time.Duration 格式您可以在 Duration#parse() javadoc 中了解更多信息。

您还可以提供以数字开头的持续时间值。 在这种情况下,如果该值仅包含一个数字,则转换器将该值视为秒。 否则,PT 会隐式添加到值的前面,以获得标准的`java.time.Duration` 格式。