shedlock实现轻量级分布式调度任务

本文以MYSQL为例,存储lock数据。更多参考ShedLock github.

Mysql 建表

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));

添加依赖

        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>4.20.1</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>4.20.1</version>
        </dependency>

配置LockProvider

@Configuration
@EnableScheduling
public class ScheduledTaskConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public LockProvider lockProvider() {
        return new JdbcTemplateLockProvider(
                JdbcTemplateLockProvider.Configuration.builder()
                        .withJdbcTemplate(new JdbcTemplate(dataSource))
                        .withTimeZone(TimeZone.getTimeZone("UTC"))
                        .build()
        );
    }
}

编写调度任务

@Service
@EnableSchedulerLock(defaultLockAtMostFor = "4m")
public class ScheduledTask {

    @Scheduled(cron = "0 0 1 * * ?")
    @SchedulerLock(name = "task1", lockAtMostFor = "60m", lockAtLeastFor = "40m")
    public void task1() {
        //task1
    }
}

测试

public class ScheduledTestTask {

    @Scheduled(cron = "0/3 * * * * *")
    @SchedulerLock(name = "t1", lockAtMostFor = "1m", lockAtLeastFor = "2s")
    public void t1() {
        System.out.println("Task 1 begin: " + LocalDateTime.now().toString());
    }

    @Scheduled(cron = "0/3 * * * * *")
    @SchedulerLock(name = "t1", lockAtMostFor = "1m", lockAtLeastFor = "2s")
    public void t2() {
        System.out.println("Task 2 begin: " + LocalDateTime.now().toString());
    }

    @Scheduled(cron = "0/3 * * * * *")
    @SchedulerLock(name = "t3", lockAtMostFor = "1m", lockAtLeastFor = "2s")
    public void t3() {
        System.out.println("Task 3 begin: " + LocalDateTime.now().toString());
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest
@Configuration
public class ScheduleTaskTest {

    @Bean
    public ScheduledTestTask ScheduledTestTask() {
        return new ScheduledTestTask();
    }

    @Test
    public void test() {
        try {
            Thread.sleep(100_000l);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

测试结果如下:
每三秒,任务t1 和 t3都会被执行,但是 t1 有两个方法,交替执行。符合预期。

Task 1 begin: 2021-03-03T17:18:54.250
Task 3 begin: 2021-03-03T17:18:54.376
Task 3 begin: 2021-03-03T17:18:57.029
Task 2 begin: 2021-03-03T17:18:57.065
Task 1 begin: 2021-03-03T17:19:00.019
Task 3 begin: 2021-03-03T17:19:00.052
Task 2 begin: 2021-03-03T17:19:03.018
Task 3 begin: 2021-03-03T17:19:03.050
Task 2 begin: 2021-03-03T17:19:06.017
Task 3 begin: 2021-03-03T17:19:06.040
Task 2 begin: 2021-03-03T17:19:09.017
Task 3 begin: 2021-03-03T17:19:09.040
Task 2 begin: 2021-03-03T17:19:12.018
Task 3 begin: 2021-03-03T17:19:12.048
Task 1 begin: 2021-03-03T17:19:15.016
Task 3 begin: 2021-03-03T17:19:15.047

参考

ShedLock github

原文地址:https://www.cnblogs.com/shoren/p/14478324.html