We have a Spring Boot application, and have scheduled tasks.
We want to deploy our application on multiple servers, so will be multiple instances of application.
How to configure Spring to run scheduled tasks only on specified servers?
This is a very wide topic. And there are many options to achieve this.
You can configure your application to have multiple profiles. For example use another profile 'cron' . And start your application on only one server with this profile. So for example, on a production environment you have three servers (S1, S2, S3), then you could run on S1 with profile prod and cron(-Dspring.profiles.active=prod,cron
). And on S2 and S3 just use prod profile(-Dspring.profiles.active=prod
).
And in code, you can use @Profile("cron")
on scheduler classes. This way it will be executed only when cron profile is active
Use a distributed lock. If you have Zookeeper in your environment, you can use this to achieve distributed locking system.
You can use some database(mysql) and create a sample code to get a lock on one of the table and add an entry. And whichever instance gets the lock, will make an entry in this database and will execute the cron job. You need to
put a check in your code, if getLock()
is successfull only then proceed with execution. Mysql has utilities like LOCK TABLES
, which you could use to get away with concurrent read/writes.
personally I would say, option 2 is the best of all.