SpringCloud技术指南系列(十三)分布式锁之Redis实现(redisson)
一、概述
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
数据库的悲观锁和乐观锁也能保证不同主机共享数据的一致性。但是却存在以下问题:悲观锁强依赖数据库的可用性,数据库是一个单点,一旦数据库挂掉,会导致业务系统不可用。
一旦悲观锁解锁操作失败,就会导致锁记录一直在数据库中,其他线程无法再获得到锁
乐观锁适合读多写少的场景,如果在分布式场景下使用乐观锁,就会导致总是更新失败,效率极低。
本文使用Redis分布式锁的开源项目redisson做分布式锁的简单实现。
redisson官网:分布式锁和同步器
代码可以在SpringBoot组件化构建https://www.pomit.cn/java/spring/springcloud.html中的LockRedis、LockSupport和LockTest组件中查看,并下载。LockSupport和LockTest是配合LockRedis的测试项目。
如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。
二、准备工作
首先是必然要安装redis的。其次,我们要了解redisson锁的种类,为了配合锁的使用,使用了LockSupport和LockTest两个项目分别做商品服务和客户端测试,多个项目使用Consul做服务注册与发现。这里会简单介绍下LockSupport、LockRedis和LockTest三个项目是如何配合使用分布式锁的。
2.1 redisson锁的种类
redisson为我们提供了很多种锁,如:
可重入锁(Reentrant Lock) :基于Redis的Redisson分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
公平锁(Fair Lock) :基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
联锁(MultiLock) :基于Redis的Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例。
红锁(RedLock) :基于Redis的Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例。
读写锁(ReadWriteLock) :基于Redis的Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks.ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。
信号量(Semaphore) :基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
可过期性信号量(PermitExpirableSemaphore) :基于Redis的Redisson可过期性信号量(PermitExpirableSemaphore)是在RSemaphore对象的基础上,为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识,释放时只能通过提交这个ID才能释放。它提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
闭锁(CountDownLatch) :基于Redisson的Redisson分布式闭锁(CountDownLatch)Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。
锁的种类虽多,但是使用方法都是类似的,本文就选择公平锁来测试使用。
2.2 LockSupport模拟商品服务
LockSupport代码可以在SpringBoot组件化构建https://www.pomit.cn/java/spring/springcloud.html中的LockSupport组件中下载,这里就只说LockSupport的功能。
LockSupport只是个简单的SpringBoot项目,使用Spring Data Jpa做数据库操作,开放以下接口做服务:goods/take 接口,做商品信息查询;
goods/page 接口,做商品分页查询;
goods/consume 接口,做商品消费。
2.3 LockRedis是分布式锁的使用
第三章节将详细介绍LockRedis项目。
2.4 LockTest模拟客户端请求
LockTest代码可以在SpringBoot组件化构建https://www.pomit.cn/java/spring/springcloud.html中的LockTest组件中下载,这里就只说LockSupport的功能。
LockTest只是个简单的SpringBoot项目,使用Feign请求LockRedis来测试分布式锁的使用。
三、分布式锁的使用
下面详细介绍LockRedis是如何使用redisson做分布式锁的。
3.1 引入依赖
需要引入数据库相关jar、jpa、spring-boot-starter-data-redis、redisson-spring-boot-starter;
因为使用了consul做服务注册发现,需要引入spring-cloud-starter-consul-discovery和spring-cloud-starter-openfeign。
依赖如下:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4.0.0
cn.pomit
springcloudwork
0.0.1-SNAPSHOT
LockRedis
LockRedis
http://maven.apache.org
UTF-8
UTF-8
1.8
2.6
org.springframework.boot
<