Springboot + redis分布式锁
1.引入redis和redisson
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redisson-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.4</version>
</dependency>
2.配置一下
application.yml里面加上 redisson配置文件
redisson:
config: classpath:redisson.yaml
新建一个redisson.yaml 填一些redis配置
singleServerConfig:
# Redis 服务器的地址
address: "redis://127.0.0.1:6379"
# 连接池的大小
connectionPoolSize: 64
# Redis 数据库索引
database: 0
# 超时时间,单位为毫秒
timeout: 3000
# Redis 命令失败重试次数
retryAttempts: 3
# 两次命令之间重试的时间间隔,单位为毫秒
retryInterval: 1500
# 发布和订阅的连接的最小数量
subscriptionConnectionMinimumIdleSize: 1
# 发布和订阅的连接池的大小
subscriptionConnectionPoolSize: 50
# 当前处理 Redis 命令的线程共享的联接
connectionMinimumIdleSize: 10
redisson还要一个配置类:
@Configuration
public class RedissonConfig {
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
return Redisson.create(config);
}
}
这样配置完基本上ok了,然后就可以直接 lock , unlock 来进行获取锁和释放锁的操作。
3.实践
下面这个场景是模拟 做一个用户匹配的操作,例如相亲配对用户,某用户很热门,许多用户争抢匹配,但是该用户只有一个,防止出现超匹配的问题,就要进行上锁
// 注入Redisson
@Autowired
private RedissonClient redissonClient;
@Override
public User matchId(Integer id) {
RLock lock = redissonClient.getLock("lock_" + id);
try {
if (lock.tryLock()) {
// 获取锁成功,执行业务逻辑
User user = userMapper.selectById(id);
if (user != null) {
// 执行匹配逻辑
// ...
System.out.println("匹配成功");
return user;
} else {
System.out.println("用户不匹配或已被匹配");
}
}
// 锁被其他人占用着
else {
System.out.println("匹配请求处理中,请稍后再试");
}
} catch (Exception e) {
Thread.currentThread().interrupt();
System.out.println("匹配请求被中断");
} finally {
// 释放锁
lock.unlock();
}
return null;
}
上面的还是一个单节点redis的操作,如果要部署集群redis的话,就可以用上 redlock的方法,
保证集群的全部节点都来管理同一个锁的状态,防止某个上锁的节点突然崩溃了,然后其它某个节点是没上锁的状态,就可以进行多次匹配的问题