Sunday, August 2, 2020

Spring scheduler lock Shedlock

Spring boot scheduler in clustered environment

Let's take an example suppose your application has as feature in which it has scheduler which runs on some predefined time interval and send an email to some concerned person.
And suppose your  application has two instances running. In that case two different instance will send mail and mail will send twice to particular person.
So to restrict this you need to apply some mechanism so that if one instance is running the scheduler at that moment second instance will not run it again. To achieve this you need to apply lock (Scheduler lock).

For this we have Java library 'Shedlock'.

1.    Add the following dependency inside pom.xml
    
       <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-spring</artifactId>
        <version>2.1.0</version>
    </dependency>
    <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-provider-jdbc-template</artifactId>
        <version>2.1.0</version>
    </dependency>

2.    Shedlock use external storage like JDBC database or other storage.
In our case we have used MySQL database, In this case we also need to create a 'table shedlock'

    CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));

3.    Now we need to create a config class for configuring shedlock

        @EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
        @Configuration
public class ShedLockConfig {
    
    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource, "shedlock");
    }

    @Bean
    public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(lockProvider)
                .withPoolSize(10)
                .withDefaultLockAtMostFor(Duration.ofMinutes(10))
                .build();
    }

4.  Now apply annotation @SchedulerLock along with your @Scheduled annotation of Scheduler class     in the following manner
 
     @SchedulerLock(name = "nameTest", lockAtMostFor = TEN_MIN, lockAtLeastFor =         TEN_MIN)

And you are Done !

Note :  Please make sure that both of your node running in same time zone and synchronized.
             

Labels: , , , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home