ShedLock解决多节点集群定时任务并发

场景描述:

最近的项目中有用到定时任务的场景,涉及到数据备份,由于多节点集群部署,导致@Scheduled所创建定时任务发生并发。之前已经用过Quartz的单机使用方法,后面研究过Quartz的解决集群并发以后还是决定采用ShedLock,相对来说比较轻量级,毕竟我们的业务场景只需要解决同一时间定时任务的集群并发问题。

ShedLock适用场景:

保证多个一个定时任务在多个服务实例之间最多只执行一次。配置相对来说最简单,对TaskName加锁的方式来实现,只需要数据库中新建一张表记录相关锁信息。Quarzt的配置较为复杂但是也更灵活。后面有时间的话会出Quartz多节点集群并发的使用。

相关依赖:

<!-- shedlock -->
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

Component注入:

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

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

mysql建表

CREATE TABLE shedlock(
name VARCHAR(64) comment ‘锁名称(name必须是主键)’,
lock_until TIMESTAMP(3) NULL comment ‘释放锁时间’,
locked_at TIMESTAMP(3) NULL comment ‘获取锁时间’,
locked_by VARCHAR(255) comment ‘锁提供者’,
PRIMARY KEY (name)
) ;

oracle 建表

CREATE TABLE SHEDLOCK (
name VARCHAR2(64 CHAR),
lock_until TIMESTAMP,
locked_at TIMESTAMP,
locked_by VARCHAR2(255 CHAR),
PRIMARY KEY (name)
);

项目注解的形式使用

启动类

@SpringBootApplication
@EnableScheduling
// 指定锁持有最大时间,会被具体的方法上相同注解覆盖
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class QuartzSpringbootMysqlApplication {

   public static void main(String[] args) {
      SpringApplication.run(QuartzSpringbootMysqlApplication.class, args);
   }
}

业务代码

/**
 * name 任务名   lockAtLeastFor 锁最小持有时间
 */
@SchedulerLock(name = "testJob",lockAtLeastFor = 2000)
@Scheduled(cron = "1 1 1 * * *")
public void testJob(){
    logger.info(Thread.currentThread().getName()+ ":"+new Date());
}

数据库中表数据

在这里插入图片描述

提示:
可以一个项目2个端口启动模拟多节点集群并发,具体操作百度。

ShedLock GitHub 相关文档

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值