文章目录
- 1、shcedulerx简介
- 2、基于mysq分布式锁实现
- 3、注解方式使用分布式锁
- 4、编码方式使用分布式锁
1、shcedulerx简介
springcloud alibaba shcedulerx看起来有点像xxl job那样的任务调度中间件,其实它是一个分布式锁框架,含有两种实现一种基于DB实现的,另一种基于云服务实现,这里看看基于DB mysql8是怎么实现的。
2、基于mysq分布式锁实现
schedulerx直接引入了net.javacrumbs.shedlock,这是一个轻量级的库,用于分布式环境中防止任务的重复执行。ShedLock 通过在数据库中维护一个锁表来实现这一点。如果选用DB shedlock来实现分布式锁,maven最好exclude云服务方案的依赖的几个jar,否则打出来的包大很多。其实自己直接基于shedlock实现分布式锁也很简单的。 schedulerx把创建锁表的sql脚本放在resources下,并做成一个starter。也就是shedulerx帮我们把DB选定为mysql,并自动建锁表,并实现springboot中自动装配。使用时只需要一个@SchedulerLock(name = "lock-xx", lockAtMostFor = "10s")
注解即可。
3、注解方式使用分布式锁
先启动一个mysql8,版本最好与shecdulerx引入的驱动版本一致。
docker run --net host --name mysql8 -v /home/mysql/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8.3.0
可以直接使用spring-cloud-scheduing-example(参考README)直接测试。
4、编码方式使用分布式锁
这个分布式锁并不与spring schedule定时任务强绑定。下面使用编程方式测试在其它场景的使用,编程更加灵活,适合那些不能或不想使用注解的情况。先要手动装配一个LockManager
对象在spring容器内。
@Configuration
public class Config {
@Autowired
LockProvider provider;
@Bean
public LockManager lockManager(){
return new DefaultLockManager(provider, runnable -> Optional.of(new LockConfiguration(Instant.now(),"mylock", Duration.ofSeconds(60),Duration.ofSeconds(30))));
}
}
新增测试案例:多实例同时启动,先获取锁的执行初始化业务
package com.alibaba.cloud.examples.schedule.job;
import java.util.concurrent.TimeUnit;
import jakarta.annotation.PostConstruct;
import net.javacrumbs.shedlock.core.LockManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyJob {
@Autowired
private LockManager lockManager;
@PostConstruct
public void appInitJob() {
lockManager.executeWithLock(() -> {
System.out.println("多实例同时启动,先获取锁的执行初始化业务,要大约20s");
try {
TimeUnit.SECONDS.sleep(20L);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}