Redis預(yù)減庫(kù)存:主要思路減少對(duì)數(shù)據(jù)庫(kù)得訪問(wèn),之前得減庫(kù)存,直接訪問(wèn)數(shù)據(jù)庫(kù),讀取庫(kù)存,當(dāng)高并發(fā)請(qǐng)求到來(lái)得時(shí)候,大量得讀取數(shù)據(jù)有可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)得崩潰。
思路:
- 系統(tǒng)初始化得時(shí)候,將商品庫(kù)存加載到Redis 緩存中保存
- 收到請(qǐng)求得時(shí)候,現(xiàn)在Redis中拿到該商品得庫(kù)存值,進(jìn)行庫(kù)存預(yù)減,如果減完之后庫(kù)存不足,直接返回邏輯Exception就不需要訪問(wèn)數(shù)據(jù)庫(kù)再去減庫(kù)存了,如果庫(kù)存值正確,進(jìn)行下一步
- 將請(qǐng)求入隊(duì),立即給前端返回一個(gè)值,表示正在排隊(duì)中,然后進(jìn)行秒殺邏輯,后端隊(duì)列進(jìn)行秒殺邏輯,前端輪詢后端發(fā)來(lái)得請(qǐng)求,如果秒殺成功,返回秒殺,成功,不成功就返回失敗。
(后端請(qǐng)求 單線程 出隊(duì),生成訂單,減少庫(kù)存,走邏輯)前端同時(shí)輪詢
- 前端顯示
等Overridepublic void afterPropertiesSet() throws Exception { List<GoodsVo> goods = goodsService.getGoodsList(); if (goods == null) { return; } for (GoodsVo goodsVo : goods) { redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount()); isOverMap.put(goodsVo.getId(), false);//先初始化 每個(gè)商品都是false 就是還有 }}
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);if (stock < 0) { isOverMap.put(goodsId, true);//沒(méi)有庫(kù)存就設(shè)置 對(duì)應(yīng)id 商品得map 為true return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);}
預(yù)減庫(kù)存:
1.先將所有數(shù)據(jù)讀出來(lái),初始化到緩存中,并以 stock + goodid 得形成存入Redis,
2.在秒殺得時(shí)候,先進(jìn)行預(yù)減庫(kù)存檢測(cè),從redis中,利用decr 減去對(duì)應(yīng)商品得庫(kù)存,如果庫(kù)存小于0,說(shuō)明此時(shí) 庫(kù)存不足,則不需要訪問(wèn)數(shù)據(jù)庫(kù)。直接拋出異常即可
內(nèi)存標(biāo)記:由于接口優(yōu)化很多基于Redis得緩存操作,當(dāng)并發(fā)很高得時(shí)候,也會(huì)給Redis服務(wù)器帶來(lái)很大得負(fù)擔(dān),如果可以減少對(duì)Redis服務(wù)器得訪問(wèn),也可以達(dá)到得優(yōu)化得效果。
于是,可以加一個(gè)內(nèi)存map,標(biāo)記對(duì)應(yīng)商品得庫(kù)存量是否還有,在訪問(wèn)Redis之前,在map中拿到對(duì)應(yīng)商品得庫(kù)存量標(biāo)記,就可以不需要訪問(wèn)Redis 就可以判斷沒(méi)有庫(kù)存了。
1.生成一個(gè)map,并在初始化得時(shí)候,將所有商品得id為鍵,標(biāo)記false 存入map中。
private Map<Long, Boolean> isOverMap = new HashMap<Long, Boolean>();等Overridepublic void afterPropertiesSet() throws Exception { List<GoodsVo> goods = goodsService.getGoodsList(); if (goods == null) { return; } for (GoodsVo goodsVo : goods) { redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount()); isOverMap.put(goodsVo.getId(), false);//先初始化 每個(gè)商品都是false 就是還有 }} boolean isOver = isOverMap.get(goodsId); if (isOver) { return Result.error(CodeMsg.MIAO_SHA_NO_STOCK); } if (stock < 0) { isOverMap.put(goodsId, true);//沒(méi)有庫(kù)存就設(shè)置 對(duì)應(yīng)id 商品得map 為true
2.在預(yù)減庫(kù)存之前,從map中取標(biāo)記,若標(biāo)記為false,說(shuō)明庫(kù)存,還有,
3.預(yù)減庫(kù)存,當(dāng)遇到庫(kù)存不足得時(shí)候,將該商品得標(biāo)記置為true,表示該商品得庫(kù)存不足。這樣,下面得所有請(qǐng)求,將被攔截,無(wú)需訪問(wèn)redis進(jìn)行預(yù)減庫(kù)存。
blog.csdn/weixin_38035852/article/details/81174986