1

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).

3 Answers3

1

You can configure the pool size. Default is 1.

Sample:

spring.task.scheduling.pool.size=10

Ezequiel
  • 136
  • 3
  • 1
    Mate, you save my day! Thank you very much! As addition: my case is possibly dupllicate with https://stackoverflow.com/questions/29796651/what-is-the-default-scheduler-pool-size-in-spring-boot – Mariusz Jędrzejewski May 05 '21 at 06:52
  • Right. It's also possible to configure it using a @Configuration, but adding to properties file is a better approach for maintenance/configuration. Let's say you have this info in a config server, then you could modify this config without any coding change. – Ezequiel May 05 '21 at 12:30
0

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(() -> ...)
);
msucil
  • 806
  • 1
  • 8
  • 15
-1

Thanks to Ezequiel, it's enough to set:

spring.task.scheduling.pool.size=10

in application.properties, now all tasks starts at the same time.