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. |
准备
要完成本指南,您需要:
-
Roughly 15 minutes
-
An IDE
-
JDK 11+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9.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)
架构
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.
完整源码
We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.
Clone the Git repository: git clone https://github.com/quarkusio/quarkus-quickstarts.git
, or download
an archive.
The solution is located in the scheduler-quickstart
directory.
Creating the Maven project
First, we need a new project. Create a new project with the following command:
For Windows users:
-
If using cmd, (don’t use backward slash
\
and put everything on the same line) -
If using Powershell, wrap
-D
parameters in double quotes e.g."-DprojectArtifactId=scheduler-quickstart"
It generates a new project including:
-
a landing page accessible on
http://localhost:8080
-
example
Dockerfile
files for bothnative
andjvm
modes -
the application configuration file
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:
quarkus extension add scheduler
./mvnw quarkus:add-extension -Dextensions='scheduler'
./gradlew addExtension --extensions='scheduler'
This will add the following to your build file:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
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 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 | 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 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 | Send back the current counter value |
Package and run the application
Run the application with:
quarkus dev
./mvnw quarkus:dev
./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:
quarkus build
./mvnw install
./gradlew build
And executed with java -jar target/quarkus-app/quarkus-run.jar
.
You can also generate the native executable with:
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.package.type=native
Scheduler Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
The syntax used in CRON expressions. Environment variable: Show more |
|
|
Scheduled task metrics will be enabled if a metrics extension is present and this value is true. Environment variable: Show more |
boolean |
|
Tracing will be enabled if the OpenTelemetry extension is present and this value is true. Environment variable: Show more |
boolean |
|
If schedulers are enabled. Environment variable: Show more |
boolean |
|
Scheduled task will be flagged as overdue if next execution time is exceeded by this period. Environment variable: Show more |
|
|
Scheduler can be started in different modes. By default, the scheduler is not started unless a Environment variable: Show more |
This is necessary for "pure" programmatic scheduling.], tooltip:halted[Just like the This can be useful to run some initialization logic that needs to be performed before the scheduler starts.] |
About the Duration format
To write duration values, use the standard You can also use a simplified format, starting with a number:
In other cases, the simplified format is translated to the
|