ShedLock: Running multiple instances runs scheduler tasks multiple times
Solution 1
dlock guarantees to have one lock at any time by using database indexes and constraints. You can simply do something like below.
@Scheduled(cron = "30 30 3 * * *")
@TryLock(name = "onlineIngestionTask", owner = SERVER_NAME, lockFor = 240000)
public void pullTasksFromRemote() {
}
See the article about using it.
Solution 2
we recently had this issue in prod where we could see multiple runs of shedlock schedulers. if you are using spring boot 2.2.1.RELEASE onwards then use below deps for shedlock
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-redis-spring</artifactId>
<version>4.8.0</version>
</dependency>
Solution 3
Please try with cron expression inside @scheduled
instead of fixedDelayString
, below scheduler run every hour.
@Scheduled(cron = "0 */1 * * *")
Comments
-
varunkr over 3 years
I am using
Shedlock
to run myscheduler
task only once if multiple instances of the service are running.I followed the documentation and this is what I did.
This is the function that needs to run periodically
@Scheduled(fixedDelayString = "300000") @SchedulerLock(name = "onlineIngestionTask", lockAtMostFor = 240000, lockAtLeastFor = 240000) public void pullTasksFromRemote() { //Code }
In my config class I have the following beans
@Bean public ScheduledLockConfiguration taskScheduler(LockProvider lockProvider) { return ScheduledLockConfigurationBuilder .withLockProvider(lockProvider) .withPoolSize(10) .withDefaultLockAtMostFor(Duration.ofMinutes(10)) .build(); } @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider(dataSource); }
The pom includes
<dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-spring</artifactId> <version>0.14.0</version> </dependency> <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-provider-jdbc-template</artifactId> <version>0.14.0</version> </dependency>
I added a table to my db, the one to which jdbc connects.
CREATE TABLE shedlock( name VARCHAR(64), lock_until TIMESTAMP(3) NULL, locked_at TIMESTAMP(3) NULL, locked_by VARCHAR(255), PRIMARY KEY (name) )
After this I tried to test the functionality by running tha pp first on port 8080. Then I use
server.port=9000
to run it again on port 9000. But both these instances start running the task. Am I missing something. Is something wrong in the implementation? Can someone give any ideas. Thanks !!