SpringBoot整合Redisson实现分布式锁
2020-08-09 本文已影响0人
salt丶
用Redisson框架实现Redis分布式锁
B站视频教学:https://www.bilibili.com/video/BV1np4y1i7DE?p=1
Redisson特性介绍
博客:https://www.jianshu.com/p/43cfa79e62a5
SpringBoot整合Redisson集群模式:
原文摘自:https://www.cnblogs.com/zengnansheng/p/11426996.html
- maven依赖
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--springboot2.0的redis整合包多出lettuce连接池,需要增加commons-pool2包
1.5的版本默认采用的连接池技术是jedis 2.0以上版本默认连接池是lettuce
spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
- yml配置
redis:
timeout: 6000ms
password: '123456'
cluster:
max-redirects: 3 # 获取失败 最大重定向次数
nodes:
- 192.168.182.129:7001
- 192.168.182.129:7002
- 192.168.182.129:7003
- 192.168.182.129:7004
- 192.168.182.129:7005
- 192.168.182.129:7006
lettuce:
pool:
max-active: 1000 #连接池最大连接数(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
- 增加一个RedisConfigProperties用于读取配置文件信息
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfigProperties {
private String password;
private cluster cluster;
public static class cluster {
private List<String> nodes;
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public RedisConfigProperties.cluster getCluster() {
return cluster;
}
public void setCluster(RedisConfigProperties.cluster cluster) {
this.cluster = cluster;
}
}
- 增加RedissonConfig
import com.zns.properties.RedisConfigProperties;
import org.redisson.Redisson;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class RedissonConfig {
@Autowired
private RedisConfigProperties redisConfigProperties;
//添加redisson的bean
@Bean
public Redisson redisson() {
//redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
List<String> clusterNodes = new ArrayList<>();
for (int i = 0; i < redisConfigProperties.getCluster().getNodes().size(); i++) {
clusterNodes.add("redis://" + redisConfigProperties.getCluster().getNodes().get(i));
}
Config config = new Config();
ClusterServersConfig clusterServersConfig = config.useClusterServers()
.addNodeAddress(clusterNodes.toArray(new String[clusterNodes.size()]));
clusterServersConfig.setPassword(redisConfigProperties.getPassword());//设置密码
return (Redisson) Redisson.create(config);
}
}
- 测试类:
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("")
public class RedisLockController {
private static String product1Count = "product1Count";//商品1的数量key
private static String lockKey = "testLockKey";//分布式锁的key
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private Redisson redisson;
/**
* 初始化设置商品数量
*
* @return
*/
@RequestMapping("/setProductCount")
public String setValue() {
redisTemplate.opsForValue().set(product1Count, "100");
return "success";
}
/**
* 模拟秒杀抢购,并发多个请求过来,查看是否出现超卖
*
* @return
*/
@RequestMapping("/spike")
public String spike() {
String flag = "success";
RLock lock = redisson.getLock(lockKey);
try {
//lock.lockAsync(5 , TimeUnit.SECONDS);
//lock.lock(5, TimeUnit.SECONDS); //设置60秒自动释放锁 (默认是30秒自动过期)
Future<Boolean> res = lock.tryLockAsync(100, 5, TimeUnit.SECONDS);
boolean result = res.get();
System.out.println("result:" + result);
if (result) {
int stock = Integer.parseInt(redisTemplate.opsForValue().get(product1Count).toString());
if (stock > 0) {
redisTemplate.opsForValue().set(product1Count, (stock - 1) + "");
} else {
flag = "fail";
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); //释放锁
}
return flag;
}
}
SpringBoot整合Redisson单机模式
对上面第四点RedissonConfig进行修改:
@Bean
public Redisson RedissonConfig(){
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);
return (Redisson) Redisson.create(config);
}