前言
本次的一个场景为秒杀的业务功能中,秒杀,我们都知道并发量是真的高,所以如何去优化这个问题便成了今天的主题(之后还会有限流来提高)。
并且此次的使用是可以大大的提高我们的并发量,和加大我们的系统稳定性。
首先,我们的一个思路:
一、redis预减库存
尽量不使用数据库连接去查询商品数量,而是通过查询redis去查询商品数量
二、redis标记商品
用一个标记点来认识这个商品是否已经为空了,这个标记点不是存放到redis里面的(后面再说),
如果这个标记点表示你的这个商品已经空了,也就不需要使用redis去查询了,也大大的减少了redis的压力。
总的来说:1、减少了数据库的压力,2、减少了redis的压力
代码:(有些代码暂时省略不看)
/**第一阶段
* QPS:1306
* 5000 * 10
* QPS: 2114
* */
@RequestMapping(value="/do_miaosha", method=RequestMethod.POST)
@ResponseBody
public Result<Integer> miaosha(HttpServletRequest request, HttpServletResponse response,
Model model, MiaoshaUser user,
@RequestParam("goodsId")long goodsId) {
model.addAttribute("user", user);
if(user == null) {//判断用户是否有cookie
return Result.error(CodeMsg.SESSION_ERROR);
}
//内存标记,减少redis访问
boolean over = localOverMap.get(goodsId);
if(over) {//商品的状态为不可秒杀就展示
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
//预减库存
long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, ""+goodsId);//10
if(stock < 0) {//如果库存只有-1就进入这里面,因为上面已经减去了一份库存
localOverMap.put(goodsId, true);//并且把这个对应的商品状态改为true(不可秒杀了)
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
//判断有无秒杀成功过后的一个redis缓存记录
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
if(order != null) {//如果有则展示不可以多次秒杀
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
/*
//判断库存
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);//10个商品,req1 req2
int stock = goods.getStockCount();
if(stock <= 0) {
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
//判断是否已经秒杀到了
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
if(order != null) {
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
*/
// GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
// //减库存 下订单 写入秒杀订单
// OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
// return Result.success(orderInfo);
//入队
MiaoshaMessage mm = new MiaoshaMessage();
mm.setUser(user);
mm.setGoodsId(goodsId);
sender.sendMiaoshaMessage(mm);
return Result.success(0);//排队中
}
1、减少数据库的压力
如何减少的第一步,
1、在我们初始化的时候,把所有的商品信息存放到redis中
2、直接从redis获取:
2、减少redis的压力
1、在我们初始化的时候,把所有的商品信息标记点存放到map集合中
2、每次从redis查询之前就提前判断是否需要使用redis。
后记
这个方法可以大大的提高数据库的一个并发能力,因为redis可以帮助减压。
后面的代码可以省略,不过也就是对数据库的增删改操作了。
项目代码:
链接:https://pan.baidu.com/s/1lLuT_BdfpdYxuKSGe_TQqw
提取码:iqeb