Quartz + Spring Boot: Concurrent execution of multiple jobs

1.5k Views Asked by At

I have simple Spring Boot (2.5) application to get multiple data from multiple sources at once. I have created 3 job classes, each of them have several tasks to do. First one have two tasks (defined in separate methods) to do, second have 3 and thirds have 2 - there's 7 in all count. Each job have this construction:

@Component
public class FirstJob {
    [...]
    @Scheduled(cron = "0 * * * * *")
    public void getLastTaskStatistics() {
        [...]
    }
    @Scheduled(cron = "0 * * * * *")
    public void getMetersStatusCount() {
        [...]
    }
}

@Component
public class SecondJob {
    [...]
    @Scheduled(cron = "0 * * * * *")
    public void getIndexStats() {
        [...]
    }
    @Scheduled(cron = "0 * * * * *")
    public void getCollectionStats() {
        [...]
    }
    @Scheduled(cron = "0 * * * * *")
    public void getActiveMetersStats() {
        [...]
    }
}

Third one is the same. As you can see, all methods have fixed and the same firing time. Everything is working almost properly, but I want to execute them in parallel, in available execution thread pool: actually observation is different, all tasks are executed in single execution task (always named scheduling-1), and also in sequential. A part of log:

2021-05-04 14:39:00.020  INFO 9004 --- [   scheduling-1] FirstJob   : getMetersStatusCount: start
2021-05-04 14:39:00.166  INFO 9004 --- [   scheduling-1] FirstJob   : getMetersStatusCount: end
2021-05-04 14:39:00.166  INFO 9004 --- [   scheduling-1] FirstJob   : getLastTaskStatistics: start
2021-05-04 14:39:00.235  INFO 9004 --- [   scheduling-1] FirstJob   : getLastTaskStatistics: end
2021-05-04 14:39:00.235  INFO 9004 --- [   scheduling-1] SecondJob  : getActiveMetersStats: start
2021-05-04 14:39:05.786  INFO 9004 --- [   scheduling-1] SecondJob  : getActiveMetersStats: end
2021-05-04 14:39:05.786  INFO 9004 --- [   scheduling-1] SecondJob  : getCollectionStats: start
2021-05-04 14:39:05.833  INFO 9004 --- [   scheduling-1] SecondJob  : getCollectionStats: end
2021-05-04 14:39:05.833  INFO 9004 --- [   scheduling-1] SecondJob  : getIndexStats: start
2021-05-04 14:39:05.902  INFO 9004 --- [   scheduling-1] SecondJob  : getIndexStats: end
2021-05-04 14:39:05.902  INFO 9004 --- [   scheduling-1] ThirdJob   : getExchangesDetails: start
2021-05-04 14:39:06.187  INFO 9004 --- [   scheduling-1] ThirdJob   : getExchangesDetails: end
2021-05-04 14:39:06.187  INFO 9004 --- [   scheduling-1] ThirdJob   : getQueueDetails: start
2021-05-04 14:39:06.303  INFO 9004 --- [   scheduling-1] ThirdJob   : getQueueDetails: end

Please help me: how to avoid single instance of Quartz executor and run in parallel all tasks in all jobs? Quartz auto configuration in application.properties is based on default values, except:

spring.quartz.properties.org.quartz.scheduler.batchTriggerAcquisitionMaxCount=5

(change made for experiment purposes, value differ from default '1', but nothing interesting happened).

2

There are 2 best solutions below

2
On

You can configure the pool size. Default is 1.

Sample:

spring.task.scheduling.pool.size=10

0
On

Why don't you try the async approach i.e. from a single @scheduled method call other method in async manners.

you can follow the approach over here How to asynchronously call a method in Java

eg:

CompletableFuture.runAsync(() -> {
    // method calls
});

or

CompletableFuture.allOf(
    CompletableFuture.runAsync(() -> ...),
    CompletableFuture.runAsync(() -> ...)
);