Scheduling Periodic Tasks

现代应用程序通常需要定期运行特定任务。在本指南中,您将学习如何计划定期任务。

如果您需要集群调度器,请使用 Quartz extension

Prerequisites

如要完成本指南,您需要:

  • Roughly 15 minutes

  • An IDE

  • 安装了 JDK 17+,已正确配置 JAVA_HOME

  • Apache Maven ${proposed-maven-version}

  • 如果你想使用 Quarkus CLI, 则可以选择使用

  • 如果你想构建一个本机可执行文件(或如果你使用本机容器构建,则使用 Docker),则可以选择安装 Mandrel 或 GraalVM 以及 configured appropriately

Architecture

在本指南中,我们创建了一个可使用 HTTP 访问的简单应用程序以获取计数器的当前值。此计数器会定期(每 10 秒)递增。

scheduling task architecture

Solution

我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。

克隆 Git 存储库: git clone $${quickstarts-base-url}.git,或下载 $${quickstarts-base-url}/archive/main.zip[存档]。

该解决方案位于 scheduler-quickstart directory中。

Creating the Maven project

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

CLI
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
    --no-code
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 --gradle--gradle-kotlin-dsl 选项。 有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。

Maven
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId={create-app-group-id} \
    -DprojectArtifactId={create-app-artifact-id} \
    -DnoCode
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

适用于 Windows 用户:

  • 如果使用 cmd,(不要使用反斜杠 \ ,并将所有内容放在同一行上)

  • 如果使用 Powershell,将 -D 参数用双引号引起来,例如 "-DprojectArtifactId={create-app-artifact-id}"

它生成一个新项目,包括:

  • 一个可通过 http://localhost:8080 访问的登陆页面

  • 针对 nativejvm 模式的 Dockerfile 示例文件

  • the application configuration file

此项目还会导入 Quarkus REST(以前的 RESTEasy Reactive)和调度程序扩展。

如果您已配置 Quarkus 项目,则可以通过在项目基本目录中运行以下命令将 `scheduler`扩展添加到项目中:

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

这会将以下内容添加到构建文件中:

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

Creating a scheduled job

在 `org.acme.scheduler`包中,创建 `CounterBean`类,内容如下:

package org.acme.scheduler;

import java.util.concurrent.atomic.AtomicInteger;
import jakarta.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`注释指示 Quarkus 每 10 秒运行此方法,前提是可使用工作程序线程(Quarkus 使用 10 个工作程序线程)。如果不可用,则应默认重新安排方法调用,即在可能的情况下调用它。计划方法的调用不依赖于先前调用的状态或结果。
4 代码非常简明。每 10 秒,计数器会递增。
5 使用类似 Cron 的表达式定义作业。带注释的方法每天上午 10:15 执行。
6 使用在 application.properties 中可配置的类似 cron 的表达式 cron.expr 定义一项作业。

Updating the application configuration file

编辑 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 * * * * ?

Creating the REST resource

创建如下 CountResource 类:

package org.acme.scheduler;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.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 Inject the CounterBean
2 发回当前计数器值

Package and run the application

使用以下内容运行应用程序:

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

在另一个终端中,运行 curl localhost:8080/count 以检查计数器值。几秒钟后,重新运行 curl localhost:8080/count 以验证计数器已被增量。

观察控制台以验证消息 Cron expression configured in application.properties 已显示,表明使用在 application.properties 配置的表达式配置的 Cron 作业已触发。

和往常一样,可以使用以下命令打包应用程序:

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

并且使用 java -jar target/quarkus-app/quarkus-run.jar 执行。

你还可以按如下方式生成本机可执行文件:

CLI
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

Scheduler Configuration Reference

Unresolved include directive in modules/ROOT/pages/scheduler.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-scheduler.adoc[]