文章目录
一、简介
Based on high-performance async and lock-free Java Redis client and Netty framework.
基于高能性异步锁自由Java Redis客户端 和 Netty框架
参数配置:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95
(1)SpringBoot2.x
配置Redisson
注意事项
在SpringBoot2.x
默认使用Lettuce
冲突:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
// 会与下面这个冲突,二者存一
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.2</version>
</dependency>
若加入redisson-spring-boot-starter
,里面会排除lettuce
// 此配置会排除 Lettuce,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
二、Demo
测试
(1)配置 + 代码
pom.xml
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.2</version>
</dependency>
RedisConfig.java
@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
return Redisson.create(config);
}
}
- Demo
@RestController
@RequestMapping("/redisson")
public class RedissonController {
@Autowired
private RedissonClient redissonClient;
@Autowired
private RedisDao redisDao;
@RequestMapping(value = "/sku/init")
public String initSku() {
redisDao.setString("product_sku", "4000");
return "初始化库存成功";
}
@RequestMapping("/sku/reduce")
public void reduce() {
RLock lock = redissonClient.getLock("product_sku");
boolean locked = false;
try {
locked = lock.tryLock(0, 10, TimeUnit.SECONDS);
if (locked) {
System.out.println("获取锁成功。。。");
} else {
System.out.println("获取锁失败。。。");
}
int sku = Integer.parseInt(redisDao.get("product_sku"));
if (--sku < 0) {
System.out.println("库存不足。。。");
return;
}
redisDao.setString("product_sku", Integer.toString(sku));
System.out.println("减库存成功: " + sku);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (!locked) {
System.out.println("获取锁失败。。。");
}
lock.unlock();
}
}
}
(2)nginx
负载均衡
-
sudo docker pull nginx
-
sudo docker run --name=nginx -p 8000:80 -d nginx
访问
localhost:8000
,即可访问 nginx 页面
- 挂载运行
# ro:只读
sudo docker run --name=nginx -p 80:80 \
-v /home/donald/Documents/Docker/Nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-d nginx
upstream redis {
server 192.168.0.143:8080;
server 192.168.0.143:8081;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://redis;
}
}
sudo docker exec -it nginx bash
运行
(3)压测
采用 ab
压测
sudo docker run --rm jordi/ab -k -c 200 -n 4000 http://192.168.0.143:8080/redisson/sku/reduce
- 使用
lock.lock( 10, TimeUnit.SECONDS);
在此压测情况下,库存可刚好消费完
压测结果如图:
- 使用
locked = lock.tryLock(1, 10, TimeUnit.SECONDS);
在此压测情况下,库存大部分情况下均消费不完
压测结果如图:
且有如下异常:
三、问题
如图: