Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Scheduler in Clustered environment

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.

like image 996
Tauri Avatar asked May 27 '16 18:05

Tauri


2 Answers

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);
}
like image 172
Lukas Avatar answered Sep 27 '22 18:09

Lukas


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.

like image 27
Will Hughes Avatar answered Sep 27 '22 19:09

Will Hughes