基于Redission框架实现redis 分布式锁
1、起初
引入依赖
<!-- spring boot redis缓存引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
controller层
/**
* @author lj on 2021/2/28.
* @version 1.0
*/
public class IndexController {
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("/test")
public String testRedisDis(){
final Boolean res = redisTemplate.opsForValue().setIfAbsent("lock_key", "liujun");
if(!res){
return "error";
}
/**
* 执行代码业务
*/
return "end";
}
}
思考?带来一系列的问题:
1、系统宕机,未释放锁即死锁(redis设置过期时间,增加try...finally...代码段)
2、业务时间太长,释放别人的锁(设置redis值为唯一uuid;在释放锁时(redisTemplate.delete("key"),增加逻辑判断只能释放自己的锁);增加看门狗来续时)
3、保证redis操作的原子性(redis设置值和设置过期时间必须同步)
2、进一步优化:
controller层
/**
* @author lj on 2021/2/28.
* @version 1.0
*/
public class IndexController {
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("/test")
public String testRedisDis(){
String lock_key = "prodect_001";
final String vaule = UUID.randomUUID().toString();
try{
final Boolean res = redisTemplate.opsForValue().setIfAbsent(lock_key, vaule,30, TimeUnit.SECONDS); //保证redis的原子性,设置时长防止redis死锁
if(!res){
return "error";
}
//TODO 开辟一个分线程使用定时器进行redis续时
/**
* 执行代码业务
*/
}finally {
//释放锁
if(vaule.equals(redisTemplate.opsForValue().get(lock_key))){ //防止释放别人的锁
redisTemplate.delete("lock_key");
}
return "end";
}
}
}
3、使用Redisson框架
1、引入Redisson的依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
2、配置为单机模式
@Bean
public Redisson redisson(){
//此为单机模式
final Config config = new Config();
config.useSingleServer().setAddress("127.0.0.1:6379").setDatabase(0);
return (Redisson) Redisson.create(config);
}
3、简单的使用代码片段

整个流程:

watch dog自动延期机制
客户端1加锁的锁key默认生存时间才30秒,如果超过了30秒,客户端1还想一直持有这把锁,怎么办呢?
简单!只要客户端1一旦加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端1还持有锁key,那么就会不断的延长锁key的生存时间。
如果时集群的话还有一个问题:就是redis的master节点宕机了,而锁没来得及复制到slave节点(待处理。。。)
总结:redisson框架其实就是上面redis过程的优化;
先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放;抢到锁后会开辟一个分线程看门狗去续时,最后在finally代码快中删除锁。

浙公网安备 33010602011771号