简介
在使用分布式锁时,经常会看到各种复制粘贴的实现,也会有很多需要注意的地方,一不小心就会出一些难以察觉的问题。还好Spring对分布式锁提供了几种方便的实现,本文简单介绍一下Redis锁的实现如何使用。
使用Redis实现分布式锁
POM文件
pom文件需要引入如下包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
-
引入
spring-boot-starter-web
包是为了方便用web来测试 -
spring-boot-starter-integration
包是包含锁的抽象 -
最后两个redis的包是相关依赖
配置SpringBoot
新建一个Redisconfig
类:
@Configuration
public class RedisConfig {
@Bean(destroyMethod = "destroy")
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
// 需要注意,REDIS_LOCK是可配置的该锁的命名空间,需要所有地方都统一用同一个
// 最后一个参数配置锁的默认过期时间,单位是MS
return new RedisLockRegistry(redisConnectionFactory, "REDIS_LOCK",10000);
}
}
在application.properties中配置对应的连接参数:
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=60000
这样就做好了相关配置,下面开始测试。
新建测试类
新建一个controller测试类:
@Slf4j
@RestController
public class TestLockController {
@Autowired
RedisLockRegistry redisLockRegistry;
@GetMapping("redisLock")
public String testLock() throws InterruptedException {
String uuid = UUID.randomUUID().toString();
// 获取对应的锁,锁的KEY是redisTestLock,存在redis中会是
// REDIS_LOCK:redisTestLock
// 前缀REDIS_LOCK就是在前面配置类中配置的
Lock redisTestLock = redisLockRegistry.obtain("redisTestLock");
// 尝试锁定对应的KEY,最多等待5秒
boolean locked = redisTestLock.tryLock(5, TimeUnit.SECONDS);
if (locked) {
try {
log.info("get lock success...id={}", uuid);
Thread.sleep(20000);
log.info("execute success..id={}", uuid);
} finally {
redisTestLock.unlock();
}
}else{
log.info("get lock failed...id={}", uuid);
}
return uuid;
}
}
测试
可以连续发起两次请求,查看结果:
curl 127.0.0.1:8080/redisLock
java控制台会输出:
get lock success...id=b529d805-e47f-462f-9252-88a446d8076f
get lock failed...id=1ff3b8e7-3215-4f73-a4a3-16ba81322499
execute success..id=b529d805-e47f-462f-9252-88a446d8076f
总结
可以看到spring提供了非常简单易用的分布式锁的实现,并且相对可靠。
参考资料
[2]示例工程:https://github.com/nereusyi/spring-boot-demos/tree/main/distributed-lock-demo
评论
发表评论