前言
本次的一個場景爲秒殺的業務功能中,秒殺,我們都知道併發量是真的高,所以如何去優化這個問題便成了今天的主題(之後還會有限流來提高)。
並且此次的使用是可以大大的提高我們的併發量,和加大我們的系統穩定性。
首先,我們的一個思路:
一、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