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

Scheduling Periodic Tasks

Modern applications often need to run specific tasks periodically. In this guide, you learn how to schedule periodic tasks.

If you need a clustered scheduler use the Quartz extension.

Requisitos previos

To complete this guide, you need:

  • Roughly 15 minutes

  • An IDE

  • JDK 11+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.8.6

  • Optionally the Quarkus CLI if you want to use it

  • Optionally Mandrel or GraalVM installed and configured appropriately if you want to build a native executable (or Docker if you use a native container build)

Arquitectura

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

Solución

Recomendamos que siga las instrucciones de las siguientes secciones y cree la aplicación paso a paso. Sin embargo, también puede ir directamente al ejemplo completo.

Clone el repositorio Git: git clone https://github.com/quarkusio/quarkus-quickstarts.git o descargue un archivo.

The solution is located in the scheduler-quickstart directory.

Creación del proyecto Maven

En primer lugar, necesitamos un nuevo proyecto. Cree un nuevo proyecto con el siguiente comando:

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

To create a Gradle project, add the --gradle or --gradle-kotlin-dsl option.

For more information about how to install the Quarkus CLI and use it, please refer to the Quarkus CLI guide.

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

To create a Gradle project, add the -DbuildTool=gradle or -DbuildTool=gradle-kotlin-dsl option.

It generates a new project including:

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

  • example Dockerfile files for both native and jvm modes

  • el archivo de configuración de la aplicación

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'

Esto añadirá lo siguiente a su archivo de construcción:

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

Creating a scheduled job

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 The get() method allows retrieving the current value.
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 Define a job with a cron-like expression cron.expr which is configurable in application.properties.

Updating the application configuration file

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 Inject the CounterBean
2 Send back the current counter value

Empaquetar y ejecutar la aplicación

Ejecuta la aplicación con:

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

In another terminal, run curl localhost:8080/count to check the counter value. After a few seconds, re-run curl localhost:8080/count to verify the counter has been incremented.

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.

As usual, the application can be packaged using:

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

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

You can also generate the native executable with:

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

Scheduler Configuration Reference

Propiedad de configuración fijada en tiempo de compilación - Todas las demás propiedades de configuración son anulables en tiempo de ejecución

Configuration property

Tipo

Por defecto

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

El formato de las duraciones utiliza el formato estándar java.time.Duration. Puede obtener más información al respecto en Duration#parse() javadoc.

También puede proporcionar valores de duración que empiecen por un número. En este caso, si el valor consiste sólo en un número, el conversor trata el valor como segundos. En caso contrario, PT se antepone implícitamente al valor para obtener un formato estándar java.time.Duration.