模拟扣库存服务,不加任何锁:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
package com.hknetty.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexContrpller {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/deduct_stock")
public String deductStock() {
//商品ID
String lockKey = "product_001";
try {
//模拟从数据库取库存
Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", realStock + "");
System.out.println("扣库存成功,剩余库存:"+realStock);
}else{
System.out.println("扣库存失败,库存不足。");
}
} finally {
}
return null;
}
}
启动端口:8080 8081 8082
配置nginx负载:
配置Redis库存数:
配置压测:
启动压测看库存结果:
加redission分布式锁
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
启动类注入bean:
/**
* Redission分布式锁
*/
@Bean
public Redisson redission() {
//单机模式
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
//分布式版本
// config.useClusterServers()
// .addNodeAddress("redis://127.0.0.1:6379")
// .addNodeAddress("redis://127.0.0.2:6379")
// .addNodeAddress("redis://127.0.0.3:6379");
return (Redisson) Redisson.create(config);
}
改造扣库存类:
package com.hknetty.redis;
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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexContrpller {
@Autowired
private Redisson redisson;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/deduct_stock")
public String deductStock() {
//商品ID
String lockKey = "product_001";
RLock rLock = redisson.getLock(lockKey);
//给业务加锁 续命
try {
rLock.lock();
//模拟从数据库取库存
Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", realStock + "");
System.out.println("扣库存成功,剩余库存:"+realStock);
}else{
System.out.println("扣库存失败,库存不足。");
}
} finally {
//关闭锁
rLock.unlock();
}
return null;
}
}
启动端口:8080 8081 8082
修改Redis库存到10000
开始压测:
来源:oschina
链接:https://my.oschina.net/u/1046143/blog/3223411