分布式锁-基于Redisson方面实现
前面俩篇文章,我们了解了基于数据库方面实现以及基于Redis方面实现的思路,我们从数据库、Redis层面了解了分布式锁的实现。这篇文章我们从Redission方面了解分布式锁。
目前来说,Redisson满足了分布式锁的全部条件,肯定是首要选择!在真正使用的话,我们肯定需要根据实际情况结合API合理的使用,Redisson查看地址。主要有配置、API介绍说明等等,非常方便。
接下来就需要我们在页面方面处理,具体如下:
利用以前学习Spring Cloud中的资源进行演示:
将服务注册在Eureka集群中:
目前Eureka出过文章,若不了解的话,请参考文章。
通过OpenFeign+Ribbon将请求分发在我们所需要的系统上:
目前Ribbon出过文章,若不了解的话,请参考文章。OpenFeign不了解的话,后续出文章进行简单介绍一下。
具体将要执行的业务程序order8002、order8003
具体看看此时业务以及配置,以8002项目为例:
引入Redisson POM文件:
<!--redissson 引入-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.7</version>
</dependency>
引入Redisson 基础信息配置文件:
@Data
@ConfigurationProperties(prefix = "redisson")
public class RedissonProperties {
// 单节点地址
private String address;
// 密码
private String password;
// 集群地址
private String[] sentinelAddresses;
// 主服务器的名称
private String masterName;
// 数据库编号
private int database = 0;
// 命令等待超时
private int timeout = 3000;
// 连接池大小
private int connectionPoolSize = 64;
// 最小空闲连接数
private int connectionMinimumIdleSize=10;
// 从节点连接池大小
private int slaveConnectionPoolSize = 250;
// 主节点连接池大小
private int masterConnectionPoolSize = 250;
}
Redisson Config文件:
@Configuration
@ConditionalOnClass(Config.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {
@Autowired
private RedissonProperties redssionProperties;
/**
* 单机模式自动装配
* @return
*/
@Bean
@ConditionalOnProperty(name="redisson.address")
RedissonClient redissonSingle() {
Config config = new Config();
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress(redssionProperties.getAddress())
.setTimeout(redssionProperties.getTimeout())
.setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
.setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
serverConfig.setPassword(redssionProperties.getPassword());
}
return Redisson.create(config);
}
/**
* 哨兵模式自动装配
* @return
*/
@Bean
@ConditionalOnProperty(name="redisson.master-name")
RedissonClient redissonSentinel() {
Config config = new Config();
SentinelServersConfig serverConfig = config.useSentinelServers()
.addSentinelAddress(redssionProperties.getSentinelAddresses())
.setMasterName(redssionProperties.getMasterName())
.setTimeout(redssionProperties.getTimeout())
.setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize())
.setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());
if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
serverConfig.setPassword(redssionProperties.getPassword());
}
return Redisson.create(config);
}
}
properties文件具体使用:
# redisson单机版
redisson.address=redis://127.0.0.1:6379
redisson.password=*****
# redisson哨兵模式
#redisson.master-name=
#redisson.password=
#redisson.sentinel-addresses=a,b
根据以上步骤完成之后,目前我们已经配置好了,接下来就是简单的使用Redisson,里面的具体方法使用规则和我们以前的Lock思路基本一样。切记:锁用完必须进行解锁,不然会造成死锁!
设置5张票,进行出票,简单案例如下:
@Autowired
private RedissonClient redissonClient;
private String KEY = "RedissonLock";
private int waitTime = 20;
private int leaseTime = 1000;
@RequestMapping("/getMyStaff")
public void getMyStaff(@RequestParam("staffIdNo") String staffIdNo){
System.out.println("进入8002....");
RLock lock = redissonClient.getLock(KEY);
try {
//在执行具体业务的时候,需要尝试获取锁
//尝试加锁,最多等待waitTime秒,上锁以后leaseTime秒自动解锁
boolean b = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
if (b){
//具体业务
Staff staff = staffService.getStaff(staffIdNo);
if (Integer.valueOf(staff.getStaffIphone())>0){
staff.setStaffIphone(Integer.valueOf(staff.getStaffIphone()) - 1+"");
staffService.updateStaff(staff);
}else{
System.out.println("不好意思,票卖完了...");
}
Thread.sleep(1000);
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
System.out.println("解锁成功!");
}
}
里面的实体类型不重要,知道思路即可!
8002服务器上日志:
8003服务器上日志:
以上就是Redisson的简单使用,具体还得根据业务以及API合理的使用相应的锁!这里的锁特别的,针对业务使用符合的锁即可!
分布式锁-基于数据库方面实现
请参考上一篇文章!
分布式锁-基于Redis方面实现
请参考上一篇文章!