缓存:分布式锁-Redission,看门狗机制
分布式锁可不是之前的一个锁,而是各种锁的总称。读写锁,闭锁,信号量等等、。
导入redisson的原生核心依赖 , redisson和之前的jedis letters一样, 都是客户端:
org.redisson redisson 3.16.8
之前用的redistemplate 操作 list hash string等都是当前进程做的,但是redisson 则是把这些对象放在redis上,由redis来操作。
配置:
package com.atguigu.gulimall.product.config; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyRedisConfig { /** * 所有对 redis 的操作,都是通过 RedissonClient对象 * * @return */ @Bean(destroyMethod = "shutdown") public RedissonClient redisson() { //创建配置 Config config = new Config(); // 这里是说使用单节点模式,而不是集群的redis模式。 config.useSingleServer().setAddress("redis://" + "192.168.155.3:6379"); //根据config对象创建 RedissonClient 实例 return Redisson.create(config); } }
===========================================
@Controller public class IndexController { @Autowired private CategoryService categoryService; @Autowired private RedissonClient redissonClient; @ResponseBody @RequestMapping("/index/hello") public String hello() { RLock lock = redissonClient.getLock("my-lock"); // 加锁,这个是阻塞式等待,没加到锁就一直在这里等着。 lock.lock(); try { System.out.println("加锁成功,执行业务,当前锁的线程ID:" + Thread.currentThread().getId()); Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("释放锁,当前锁的线程ID:" + Thread.currentThread().getId()); lock.unlock();//解锁 } return "hello"; }
redis中的key也包含了线程ID 95 :
30s后业务执行完释放锁打印:
===================================
假设,解锁代码没有执行,执行业务的时候程序闪断了,服务宕机了,解锁代码没执行,redisson会出现死锁吗?
答案是 不会死锁。
在redis中可以发现,这个锁有个TTL 的值。
redisson的强大之处:
- 锁的自动续期,如果业务时间很长,他会自动续期,不用担心锁会被自动删掉,加锁的时候不指定,默认加30s的时间,续期也是30s
- 加锁的业务运行完成,就不会续期了,即使不手动解锁,也会自动在30s 的时间出自动解锁。
=================================================
加锁的时候,如果指定时间,不会自动续期。
* 如果我们传递了锁的超时时间,就会给redis发送超时脚本来进行占锁 默认超时时间就是我们指定的
* 如果我们未指定,就使用 30 * 1000 [LockWatchdogTimeout] 看门狗默认时间
* 只要占锁成功 就会启动一个定时任务 任务就是重新给锁设置过期时间 这个时间还是 [LockWatchdogTimeout] 的时间 1/3 看门狗的时间续期一次 续成满时间。
定时任务,每隔十秒就续期,续成满时间30s
业务如果30s都没做完,那就是业务的问题了。实战用的多的还是指定过期时间。