Spring Boot + Redis 解決商品秒殺庫(kù)存超賣,看這篇文章就夠了
今日 Java 干貨
剛剛發(fā)表
查看:15400回復(fù):165
掃描下方二維碼,后臺(tái)回復(fù) 筆記,免費(fèi)獲取 10萬(wàn)字Springboot學(xué)習(xí)筆記。
?長(zhǎng)按上方二維碼 2 秒回復(fù)「筆記」即可獲取資料作者:濤哥談籃球
來(lái)源:toutiao.com/i6836611989607809548
問(wèn)題描述在眾多搶購(gòu)活動(dòng)中,在有限的商品數(shù)量的限制下如何保證搶購(gòu)到商品的用戶數(shù)不能大于商品數(shù)量,也就是不能出現(xiàn)超賣的問(wèn)題;還有就是搶購(gòu)時(shí)會(huì)出現(xiàn)大量用戶的訪問(wèn),如何提高用戶體驗(yàn)效果也是一個(gè)問(wèn)題,也就是要解決秒殺系統(tǒng)的性能問(wèn)題。本文主要介紹基于redis 實(shí)現(xiàn)商品秒殺功能。先來(lái)跟大家講下大概思路。
總體思路就是要減少對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),盡可能將數(shù)據(jù)緩存到Redis緩存中,從緩存中獲取數(shù)據(jù)。
在系統(tǒng)初始化時(shí),將商品的庫(kù)存數(shù)量加載到Redis緩存中;接收到秒殺請(qǐng)求時(shí),在Redis中進(jìn)行預(yù)減庫(kù)存,當(dāng)Redis中的庫(kù)存不足時(shí),直接返回秒殺失敗,否則繼續(xù)進(jìn)行第3步;將請(qǐng)求放入異步隊(duì)列中,返回正在排隊(duì)中;服務(wù)端異步隊(duì)列將請(qǐng)求出隊(duì),出隊(duì)成功的請(qǐng)求可以生成秒殺訂單,減少數(shù)據(jù)庫(kù)庫(kù)存,返回秒殺訂單詳情。當(dāng)后臺(tái)訂單創(chuàng)建成功之后可以通過(guò)websocket 向用戶發(fā)送一個(gè)秒殺成功通知。前端以此來(lái)判斷是否秒殺成功,秒殺成功則進(jìn)入秒殺訂單詳情,否則秒殺失敗。
下面直接上代碼系統(tǒng)初始化的時(shí)候?qū)⒚霘⑸唐穾?kù)存放入redis緩存

第二創(chuàng)建消息隊(duì)列(這里為了方便,我直接使用redis隊(duì)列來(lái)進(jìn)行模擬操作)

第三 配置RedisTemplate序列化

下面創(chuàng)建一個(gè)接口,在這個(gè)接口中創(chuàng)建10000個(gè)線程來(lái)模擬用戶商品搶購(gòu)場(chǎng)景


這里使用到了redis api中的decrement操作,預(yù)先減輕用戶搶購(gòu)的數(shù)量,同時(shí)判斷redis中的庫(kù)存是否大于用戶搶購(gòu)數(shù)量,如果小于0,直接提示用戶秒殺失敗,否則秒殺成功,進(jìn)入redis消息隊(duì)列執(zhí)行數(shù)據(jù)庫(kù)建庫(kù)存操作。以上操作注意保證redis緩存與數(shù)據(jù)庫(kù)庫(kù)存數(shù)據(jù)保持一致性。

下面測(cè)試演示

初始化商品庫(kù)存100,在測(cè)試一萬(wàn)并發(fā)量后,最終發(fā)現(xiàn)不會(huì)不會(huì)出現(xiàn)超賣問(wèn)題。因?yàn)檫@里一萬(wàn)個(gè)并發(fā),每個(gè)并發(fā)搶購(gòu)10件商品。經(jīng)過(guò)redis減庫(kù)存之后,最后只會(huì)有10個(gè)線程去更新數(shù)據(jù)庫(kù)。
文末福利
免費(fèi)分享一套我親自寫(xiě)的10萬(wàn)字Springboot學(xué)習(xí)筆記(帶完整目錄)以及源碼,下圖是pdf版本的部分截圖。

獲取方式:
掃描下方二維碼,回復(fù)「筆記」
?長(zhǎng)按上方二維碼 2 秒回復(fù)「筆記」即可獲取資料
希望大家拿去好好學(xué)習(xí),如果覺(jué)得不錯(cuò),也可以把文章分享給其他小伙伴,一起學(xué)習(xí)!
點(diǎn)贊是最大的支持 ![]()
