秒殺搶購思路解析


秒殺描述:

網上競拍的一種新方式。所謂“秒殺”,就是網絡賣家發布一些超低價格的商品,所有買家在同一時間網上搶購的一種銷售方式。由於商品價格低廉,往往一上架就被搶購一空,有時只用一秒鍾。

常見秒殺方式:

1、限時,例如:小米手機 限時、限量搶購,還有淘寶、京東等電商平台等。

2、一元搶購  例如:例如:1元搶購手機、電器等。

3.限時、限量搶購  例如:12306 搶票 還有部分電商平台等。

秒殺搶購的特征:

1、短時間內並發量非常大,高並發問題

Java實現微服務秒殺搶購思路分析

  1. 秒殺搶購前端優化方案
  2. 秒殺搶購如何防止超賣問題
  3. 基於MQ和Redis實現秒殺搶購
  4. 秒殺搶購如何防止偽造

秒殺過程中常見問題:

前端問題:

1、前端服務器帶寬增加

2、用戶重復提交訂單。將提交按鈕置灰色,不可點擊。

秒殺前端優化方案:

1、把靜態資源(css\js\img\mp4)存放到第三方靜態服務器上面,例如:七牛雲、騰訊雲ONS、阿里雲等。

2、增加服務器的帶寬,確保網站的加載速度。1兆帶寬=128kb/s   

舉栗子:假如現在網站是1兆帶寬,加載一個頁面需要640kb  加載網頁的時間:640/128=5s。加載網頁需要5秒的時間,這樣導致用戶體驗肯定不好,所有如果想要1s 內加載處理這個頁面 需要將帶寬增加 到 5兆帶寬。但是這樣成本過高,而且治標不治本。可以使用動靜分離、CDN加速等方式。

3、使用CDN加速,提高網站訪問速度。CDN好處:遵循就近訪問原則,減少客戶端與服務器端的帶寬傳輸。

4、使用動靜分離,核心

后端問題:

1、商品庫存超賣問題   解決方案:使用redis 分布式鎖、樂觀鎖、MQ 實現 。

方案1:根據 商品Id、庫存>0 修改庫存數量,防止超賣問題。
update seckill set inventory=inventory-1, version=version+1 where productId=#{productId} and inventory>0

不使用 版本號,解決超賣問題,使用了 MySql 自帶的行鎖機制。屬於悲觀鎖

方案2:樂觀鎖:使用 version 版本號。需要在執行 修改 庫存之前,先查詢一下該商品庫存的版本號,然后在根據版本號 商品Id庫存>0 為條件修改庫存的數量,防止超賣問題。

select id ,productId ,productName , inventory , startTime , endTime , createTime , version from seckill where productId=#{productId};

update seckill set inventory=inventory-1, version=version+1 where productId=#{productId} and inventory>0 and version=#{version};

使用 version 版本號解決超賣問題,屬於樂觀鎖。

方案1與方案2 比較:

1、推薦使用方案2解決超賣問題。

2、場景比較:

方案1:200個請求,100庫存,100個請求都能夠搶購成功。

方案2:200個請求,100個庫存,可能只有68個請求搶購成功,還剩余32個商品庫存。還可以進行第二次搶購。防止一次性被搶完,可以使用這種方案。

2、單台服務器扛不住大量請求  解決方案:使用集群部署

3、如何限制用戶的操作頻率,如何防止用戶作弊行為,利用工具進行秒殺搶購。

方案:redis 是單線程的 線程安全的。基於Redis 的 setNx(key,value,timtout);解決,如果key 存在,則返回 false,如果key 不存在則返回 true。

秒殺服務為什么需要以微服務方式單獨部署:

目的:與其他服務互不影響、可以使用 docker部署實現快速擴容。

當修改商品庫存的請求過多時,數據庫訪問壓力過大,如何解決:

1、使用分表分庫

2、使用MQ異步實現修改庫存數量

3、如果秒殺的請求過多,對數據庫頻繁的進行IO操作,可能會導致數據庫崩潰的問題。

解決方案:使用令牌桶提前生成好對應庫存的令牌,存放在令牌桶中誰能搶到token,就放入到 MQ 中 實現異步修改庫存。

服務限流、服務保護、安全性問題。可以使用驗證碼進行驗證。

秒殺搶購中修改庫存數量如何減少數據庫IO操作?

在高並發情況下,如果突然有10w個不同的用戶請求進行秒殺,但是商品的庫存數量只有100個,那么這個時候可能會出現10w個請求執行修改秒殺庫存的sql語句,這時候可能會出現數據庫訪問壓力承受不了,導致數據庫爆掉。

解決方案:數據庫分表分庫、讀寫分離、使用redis 緩存減少數據庫的訪問壓力

推薦秒殺方案:基於MQ+庫存令牌桶實現。

同時有10w個請求實現秒殺,商品庫存只有100個 實現只需要修改庫存100次就可以了。

方案實現流程:提前對商品庫存生成好令牌(100個令牌),在10w個請求中,只要誰搶到了令牌誰就能夠秒殺成功。獲取到秒殺令牌后,在使用MQ異步實現減庫存的操作。

如果采用 MQ 實現秒殺搶購,秒殺接口不能立刻的拿到秒殺結果,因為MQ 是異步形式的。

1、前端調用秒殺接口如果秒殺成功的話,返回正在派對中......

2、前端寫一個定時器使用 秒殺 token 查詢秒殺是否成功,如果MQ 消費的速度非常快的話,1-2s 就可以拿到結果。

需要為商品庫存生成對應庫存數量的 token,key 為 商品Id,value 為 list集合。使用的是 redis 的lList集合方式。

如何防止庫存超賣問題

1、使用數據庫樂觀鎖(CAS無鎖機制)

2、使用 Redis實現分布式鎖,因為 Redis 天然的線程安全(原子性)。不建議使用 zookeeper ,因為zookeeper無法保證數據原子性問題。

3、使用MQ異步形式實現修改庫存(用戶等待時間過長)。推薦

 

 

該博客內容來自螞蟻課堂:http://www.mayikt.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM