分布式系列(二) | Redisson分布式锁
分布式锁
1、概述
- Redisson 是一个在Redis的基础上实现的
Java
驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。 - Redisson 的宗旨是:促进使用者对
Redis
的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
2、四个条件
为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:
- 第一个:互斥性,在任何时刻,只有一个客户端能持有锁。
- 第二个:不会发生死锁,即使有一个客户端在获取锁操作时候崩溃了,也能保证其他客户端能获取到锁。
- 第三个:解铃还须系铃人,解锁加锁必须同一个客户端操作。
- 第四个:加锁和解锁必须具备原子性
3、引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
4、配置类别
创建RedissonConfig
配置类
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedissonConfig {
private String host;
private String password;
private String port;
private int timeout = 3000;
private static String ADDRESS_PREFIX = "redis://";
/**
* 自动装配
*
*/
@Bean
RedissonClient redissonSingle() {
Config config = new Config();
if(!StringUtils.hasText(host)){
throw new RuntimeException("host is empty");
}
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress(ADDRESS_PREFIX + this.host + ":" + port)
.setTimeout(this.timeout);
if(StringUtils.hasText(this.password)) {
serverConfig.setPassword(this.password);
}
return Redisson.create(config);
}
}
配置 application.yml
spring:
data:
redis:
host: 192.168.2.5
port: 6379
database: 0
timeout: 1800000
password:
jedis:
pool:
max-active: 20 #最大连接数
max-wait: -1 #最大阻塞等待时间(负数表示没限制)
max-idle: 5 #最大空闲
min-idle: 0
5、代码实现
public void testLockRedisson() {
// 1.获取锁 可重入锁
RLock lock = redissonClient.getLock("lock1");
// 2.加锁
try {
// 阻塞 默认过期30s 看门狗:自动续期
lock.lock();
// 设置过期 10s
//lock.lock(10, TimeUnit.SECONDS);
// 等待时间 、 设置过期时间
// lock.tryLock(30, 10, TimeUnit.SECONDS);
// 3.业务代码
String value = redisTemplate.opsForValue().get("num");
if (StringUtil.isBlank(value)) {
return;
}
int num = Integer.parseInt(value);
redisTemplate.opsForValue().set("num", String.valueOf(++num));
} finally {
//4.释放锁
lock.unlock();
}
}
6、Redisson 看门狗
基于**`Redis`**的**`Redisson`**分布式可重入锁**`RLock` `Java`**对象实现了**`java.util.concurrent.locks.Lock`**接口。
如果负责储存这个分布式锁的**`Redisson`**节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现**锁死**的状态。为了避免这种情况的发生,**`Redisson`**内部提供了一个**监控锁的看门狗**,它的作用是在**`Redisson`**实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改**`Config.lockWatchdogTimeout来`**另行指定。
另外**Redisson
还通过加锁的方法提供了leaseTime
**的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
看门狗原理:
只要线程一加锁成功,就会启动一个**`watch dog`**看门狗,它是一个**后台线程**,会每隔**10秒检查**一下,如果线程还持有锁,那么就会**不断的延长锁key**的生存时间。因此,**`Redisson`**就是使用**`watch dog`**解决了`锁过期释放,业务没执行完问题`。
- 如果我们指定了锁的超时时间,就发送给**
Redis
**执行脚本,进行占锁,默认超时就是我们制定的时间,不会自动续期; - 如果我们未指定锁的超时时间,就使用
lockwatchdogTimeout= 30 * 1000
【看门狗默认时间】
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 码农Stormling!
评论
ValineGitalk