SpringBoot3.1.0集成redisson分布式锁框架基本使用
案例环境:
pom依赖:
<parent> <!--springBoot版本-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--redisson 下面两个pom依赖,有任意一个就行-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.22.1</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.21.1</version>
</dependency>
yml配置:
server:
port: 9888
spring:
data:
redis:
url: localhost
port: 6379
注意:
先在redis中创建一个名为 num 的缓存,值为 100
controller
@RestController
public class RedissonTest {
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@SuppressWarnings("all")
@GetMapping("redisson")
public String redisson() {
int num = (int) redisTemplate.opsForValue().get("num");
if (num > 0) {
System.out.println("扣减库存成功!当前库存数==:" + --num);
redisTemplate.opsForValue().set("num", num);
return String.valueOf(num);
} else {
System.out.println("库存已经没了!");
return "库存已经没了!";
}
}
}
使用springBoot启动服务,并且再复制一份启动,模拟多台服务器
创建第二份服务过程:
-Dserver.port=9889
配置Nginx配置:
通过访问localhost:9001 轮询负载均衡到 localhost:9888和localhost:9889
nginx.conf配置如下
http {
upstream backend {
server localhost:9888;
server localhost:9889;
}
server {
listen 9001;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
}
启动nginx
访问 localhost:9001/redisson
使用jemter模拟并发场景
启动jemter测试:
可以看到出现了并发问题,那么现在修改下代码,引入分布式锁框架redisson
代码更改如下
@RestController
public class RedissonTest {
@Autowired
private Redisson redisson; // 注入Redisson对象
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@SuppressWarnings("all")
@GetMapping("redisson")
public String redisson() {
RLock lock = redisson.getLock("test"); // 获取redisson分布式锁对象
try {
lock.lock(); // 加锁
int num = (int) redisTemplate.opsForValue().get("num");
if (num > 0) {
System.out.println("扣减库存成功!当前库存数==:" + --num);
redisTemplate.opsForValue().set("num", num);
return String.valueOf(num);
} else {
System.out.println("库存已经没了");
return "库存已经没了";
}
} finally {
lock.unlock(); //解锁
}
}
}
然后重启服务再次启动jmeter测试
可以发现已经解决了并发的问题
总结
redisson分布锁的框架原理,是使用了redisTemplate.opsForValue().setIfAbsent(key,value)加锁,底层是redis SETNX命令,具体的框架底层原理请参考链接 https://blog.csdn.net/m0_37900506/article/details/118466891