Search code examples
springspring-bootjobsjob-scheduling

Spring and scheduled tasks on multiple instances


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?


Solution

  • This is a very wide topic. And there are many options to achieve this.

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

    2. Use a distributed lock. If you have Zookeeper in your environment, you can use this to achieve distributed locking system.

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

    4. Use Spring shedlock. This library aims to solve this problem quite elegantly and with minimum code. Have a look at an example here

    personally I would say, option 2 or option 4 is the best of all.