引入所需依赖包
<!--分布式锁--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.10.1</version> </dependency>
编写Config配置类
此处由于我本地测试的redis没有设置密码所以取消了设置密码步骤,如果是redis集群则使用集群模式。
@Configuration @Data public class AppConfig { @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private String redisPort; // @Value("${spring.redis.password}") // private String redisPwd; @Bean public RedissonClient redissionCLient() { Config config = new Config(); // 单机模式 config.useSingleServer() // .setPassword(redisPwd) .setAddress("redis://" + redisHost + ":" + redisPort); // 集群模式 // config.useClusterServers().addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001"); return Redisson.create(config); } }
编写测试案例
这里睡眠十秒钟模拟正在处理逻辑,一个线程加锁成功后正在处理逻辑还未解锁,另外一个线程准备获取锁
@ApiOperation("加锁测试") @GetMapping("lock") public JsonData lock() { RLock lock = redissonClient.getLock("lock:coupon:19"); lock.lock(); try { // 加锁成功 log.info("加锁成功,处理业务逻辑,线程{}",Thread.currentThread().getId()); TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 解锁 lock.unlock(); log.info("解锁成功,其他线程可以进入,线程{}",Thread.currentThread().getId()); } return JsonData.buildSuccess(); }
启动两个端口测试
分别是9002,9005,浏览器输入测试地址进行测试
测试结果
9002处理结束之后才处理9005
附加,Redisson是怎样解决分布式锁的⾥⾯的坑
问题 : Redis锁的过期时间⼩于业务的执⾏时间该如何续
期?
watch dog看⻔狗机制
负责储存这个分布式锁的Redisson节点宕机以后,⽽且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。或者业务执⾏时间过⻓导致锁过期,为了避免这种情况的发⽣,Redisson内部提供了⼀个监控锁的看⻔狗,它的作⽤是在Redisson实例被关闭前,不断的延⻓锁的有效期。Redisson中客户端⼀旦加锁成功,就会启动⼀个watchdog看⻔狗。watch dog是⼀个后台线程,会每隔10秒检查⼀下,如果客户端还持有锁key,那么就会不断的延⻓锁key的⽣存时间
默认情况下,看⻔狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另⾏指定