I am using spring scheduler using @Scheduled annotation to schedule a job that runs a file generation service. The application is deployed on 5 separate nodes of tomcat in clustered environment for load balancing and fail over. Because of this, service is scheduled 5 times which is never expected. Is there a way to configure the scheduler to be run only on the current node?
There is an approach that uses database to figure out the current alive node and invoking the scheduler for that particular instance here
Another approach is to use quartz scheduler
Since I could not make major changes to the deployed application, is there a simple solution to the issue? Please advise.
You can use ShedLock project. You just annotate tasks which should be locked when executed
@Scheduled( ... )
@SchedulerLock(name = "scheduledTaskName")
public void scheduledTask() {
// do something
}
Configure Spring and a LockProvider (SQL and Mongo currently supported)
@Bean
public TaskScheduler taskScheduler(LockProvider lockProvider) {
return SpringLockableTaskSchedulerFactory
.newLockableTaskScheduler(poolSize, lockProvider);
}
You can also use dlock to execute a scheduled task only once over multiple nodes. You can simply do something like below.
@Scheduled(cron = "30 30 3 * * *")
@TryLock(name = "jobLock", owner = SERVER_NAME, lockFor = THREE_MINUTES)
public void runJobsOnce() {
List<Job> jobs = jobService.getJobs();
for(Job job: jobs){
runJob(job);
}
}
See the article about using it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With