使用redisson做分布式锁
分布式锁
在java中单体应用中,我们如果想要保证一个接口或者服务、方法当下只有一个线程在运行,我们可以通过JDK提供的Lock、Semaphore、同步锁等多种方式实现只有一个线程在运行。
在微服务系统中,我们的单体应用会变成多个节点,只靠JDK本身的锁只能控制一个节点的运行,所以我们需要一个可以控制全局的锁来控制系统的运行,这就是所谓的分布式锁。
Zk redis 等中间件都可以做分布式锁,优缺点也各不相同,在我们现在的系统中zk的直接操作还是比较少,更多的是作为dubbo的服务信息储存,所以用Redis做锁的载体。
Redisson是我国的一位大牛写的一个框架,可以使用 redis做类似JDK的全局队列、锁、集合等N多封装好的东西,同时也是redis官方推荐的框架。官方文档地址:
https://github.com/redisson/redisson/wiki
这个主要是入门。
我们的SpringBoot 版本是 1.5.8 ,首先引入SpringBoot starter的依赖,如下:
<dependency>
<groupId>org.redissongroupId>
<artifactId>redisson-spring-boot-starterartifactId>
<version>2.15.1version>
dependency>
Application.yml 中的Redis配置不需要改变,与spring系统兼容,直接可以在代码中使用redisson的api了。
代码:
@Autowired RedissonClient redissonClient; @Valid @ApiOperation(value = "测试接口", notes = "通过接口 ,对测试服务连通性", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @RequestMapping(value = "test", method = RequestMethod.POST) public Responsetest() { RLock rLock = redissonClient.getLock("test1"); rLock.lock(); try { Thread.sleep(1000l); } catch (InterruptedException e) { e.printStackTrace(); } if (log.isDebugEnabled()) { log.debug("test welcome........."); } rLock.unlock(); return Response.success("响应成功"); }
我本来使用了最新版的starter但是发现有reactor的东西,造成了启动报错,后来去maven仓库翻了一下,发现2.15.1之后的版本,用的都是2.0以后的springBoot,那2.0之后的用的都是Spring 5的版本,所以往后推,看到2.15.1依然是SpringBoot1.5.X 系列的,
所以使用这个版本,没有报错。
这个版本没有redLock,不过无所谓了,应该没啥问题,没那么大的并发,另外,测试过程中,发现那个tryLock有点儿坑,获取锁的时间,没什么用,后续的代码还是可以执行,执行完成后会报错。我们应该会直接用Lock。
所谓的redLock就是 Redis主节点没有写到从节点的时候,另外一个应用的节点去redis同时查看这个锁是否存在,造成死锁,或者没有保证锁的安全性(题外话,网上有很多资料)
|