Skip to content

@Schedule 通过 ShedLock 实现分布式定时任务

默认的 @Schedule 注解实现的定时任务是单个应用的,当开启了多个实例,每个实例中都会执行一次。
此时可通过添加 shedlock-spring 包来支持这种分布式场景。

1. 在 pom.xml 中添加依赖

这里使用的版本是 4.20.1

xml
<!-- ShedLock -->
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>${shedlock.version}</version>
</dependency>
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>${shedlock.version}</version>
</dependency>

2. 添加配置文件

@EnableScheduling 注解用于启用定时任务。
@EnableSchedulerLock 注解用于启用 ShedLock

这里使用数据库来实现任务的锁竞争,所以定义了一个 JdbcTemplateLockProvider 类型的 Bean

更多的锁实现方式请参考 这篇文章

java
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.sql.DataSource;

/**
 * @author jiajia
 */
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class ShedLockConfiguration {

    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }
}

3. 创建数据库表

使用数据库锁时需要创建对应的表。

sql
CREATE TABLE shedlock(
  name VARCHAR(64),
  lock_until TIMESTAMP(3) NULL,
  locked_at TIMESTAMP(3) NULL,
  locked_by  VARCHAR(255),
  PRIMARY KEY (name)
)

4. 创建定时任务

注解的属性值使用了 SpEL ,以方便在配置中心中修改。

lockAtMostFor:锁最长保留时间(防止某个应用实例宕机导致锁被长时间占用)
lockAtLeastFor:锁最短保留时间(防止多个应用实例间有时间差)

java
@Scheduled(cron = "${task.sample.cron:0 0/10 * * * ?}")
@SchedulerLock(name = "sample-task",
        lockAtMostFor = "${task.sample.lock-at-most-for:60s}",
        lockAtLeastFor = "${task.sample.lock-at-least-for:10s}")
public void sampleTask() {
    // do something
}

参考

  1. SpringBoot 集成 ShedLock 实现分布式定时锁
  2. ShedLock 锁,防止 spring 定时调度@Scheduled 注解在分布式环境下重复执行

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.