JAVA全系列 教程
3762个小节阅读:7093.9k
目录
C语言快速入门
JAVA全系列 教程
面向对象的程序设计语言
Python全系列 教程
Python3.x版本,未来主流的版本
人工智能 教程
顺势而为,AI创新未来
大厂算法 教程
算法,程序员自我提升必经之路
C++ 教程
一门通用计算机编程语言
微服务 教程
目前业界流行的框架组合
web前端全系列 教程
通向WEB技术世界的钥匙
大数据全系列 教程
站在云端操控万千数据
AIGC全能工具班
A A
White Night
一个物品库存里有100件,但是由于秒杀环境的高并发,导致该物品被卖出超过100件。这就是超卖问题。
我们通过一个测试演示超卖现象:
新增两个秒杀商品
修改秒杀下单的代码,提示订单生成。
xxxxxxxxxx
@Override
public Orders createOrder(Orders orders) {
// 1.生成订单对象
orders.setId(IdWorker.getIdStr()); // 手动使用雪花算法生成订单id
orders.setStatus(1); // 订单状态未付款
orders.setCreateTime(new Date()); // 订单创建时间
orders.setExpire(new Date(new Date().getTime() + 1000 * 60 * 5)); // 订单过期时间
// 计算商品价格
CartGoods cartGoods = orders.getCartGoods().get(0);
Integer num = cartGoods.getNum();
BigDecimal price = cartGoods.getPrice();
BigDecimal sum = price.multiply(BigDecimal.valueOf(num));
orders.setPayment(sum);
// 2.减少秒杀商品库存
// 查询秒杀商品
SeckillGoods seckillGoods = findSeckillGoodsByRedis(cartGoods.getGoodId());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// 查询库存,库存不足抛出异常
if (seckillGoods == null || seckillGoods.getStockCount() <= 0) {
throw new BusException(CodeEnum.NO_STOCK_ERROR);
}
// 减少库存
seckillGoods.setStockCount(seckillGoods.getStockCount() - cartGoods.getNum());
redisTemplate.boundHashOps("seckillGoods").put(seckillGoods.getGoodsId(), seckillGoods);
// 3.将订单数据保存到Redis中
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置订单1分钟过期
redisTemplate.opsForValue().set(orders.getId(), orders, 100, TimeUnit.MINUTES);
/**
* 给订单创建副本,副本的过期时间长于原订单
* redis过期后触发过期事件时,redis的数据已经过期,此时只能拿到key,拿不到value
* 而过期事件需要回退商品库存,必须拿到value即订单详情,才能拿到商品数据,进行回退操作
* 我们保存一个订单副本,过期时间长于原订单,我们就可以通过副本拿到订单数据
*/
redisTemplate.opsForValue().set(orders.getId() + "_copy", orders, 101, TimeUnit.MINUTES);
System.out.println("下单成功,订单号:"+orders.getId());
return orders;
}
重启秒杀服务
由于Postman只能批量发送是串行发送,也就是第一个请求发送完成才能发送第二个请求,无法模拟高并发下单,所以我们需要使用另一个测试工具——JMeter。
解压JMeter,启动JMeter(启动JMeter要求我们的电脑必须安装JDK并配置好环境变量)。
添加线程组,在线程组下添加HTTP请求、查看结果树。在HTTP请求下添加HTTP信息头管理器。
在HTTP信息头管理器下添加请求头。
添加HTTP请求
分别测试普通并发和高并发情况下,秒杀商品下单是否会出现超卖现象