秒杀抢购系统的实现
一、秒殺系統(tǒng)介紹及遇到的挑戰(zhàn)
1. 什么是秒殺?
秒殺是網(wǎng)絡(luò)賣家發(fā)布一些超低價(jià)格的商品,所有買家在同一時(shí)間網(wǎng)上搶購(gòu)的一種銷售方式。由于價(jià)格比價(jià)低廉,一上架就被搶購(gòu)一空,有時(shí)只需要幾秒鐘,所以非常考驗(yàn)系統(tǒng)的并發(fā)能力。當(dāng)然,秒殺常見(jiàn)形式有1元秒殺、低價(jià)限量秒殺(小米限量秒殺,12306分段限量秒殺)、低價(jià)限時(shí)限量秒殺(電商平臺(tái)偏多)。
2. 秒殺業(yè)務(wù)分析
1.正常電子商務(wù)流程
(1)查詢商品;(2)創(chuàng)建訂單;(3)扣減庫(kù)存;(4)更新訂單;(5)付款;(6)賣家發(fā)貨
2.秒殺業(yè)務(wù)特性流程
(1)低廉價(jià)格;(2)大幅推廣;(3)瞬時(shí)售空;(4)一般是定時(shí)上架;(5)時(shí)間短、瞬時(shí)并發(fā)量高;
3.秒殺實(shí)現(xiàn)技術(shù)挑戰(zhàn)
(1)秒殺技術(shù)挑戰(zhàn)
假設(shè)某網(wǎng)站秒殺活動(dòng)只推出一件商品,預(yù)計(jì)會(huì)吸引1萬(wàn)人參加活動(dòng),也就說(shuō)最大并發(fā)請(qǐng)求數(shù)是10000,秒殺系統(tǒng)需要面對(duì)的技術(shù)挑戰(zhàn)有:后面將談到的前端層面和業(yè)務(wù)層面的問(wèn)題
(2)對(duì)現(xiàn)有網(wǎng)站業(yè)務(wù)造成沖擊
秒殺活動(dòng)只是網(wǎng)站營(yíng)銷的一個(gè)附加活動(dòng),這個(gè)活動(dòng)具有時(shí)間短,并發(fā)訪問(wèn)量大的特點(diǎn),如果和網(wǎng)站原有應(yīng)用部署在一起,必然會(huì)對(duì)現(xiàn)有業(yè)務(wù)造成沖擊,稍有不慎可能導(dǎo)致整個(gè)網(wǎng)站癱疾。
解決方案:將秒殺系統(tǒng)獨(dú)立部署,甚至使用獨(dú)立域名,使其與網(wǎng)站完全隔離。
秒殺系統(tǒng)架構(gòu)圖:
3. 秒殺搶購(gòu)實(shí)現(xiàn)遇到的問(wèn)題
- 前端層面:
1.突然增加的網(wǎng)絡(luò)及服務(wù)器帶寬
2.防止用戶重復(fù)提交 - 業(yè)務(wù)層面:
1.如何防止商品超賣問(wèn)題
2.服務(wù)器單臺(tái)機(jī)器承受不了
3.如何限制用戶操作頻率
4.如何防止用戶作弊行為
注:秒殺本質(zhì)也屬于高并發(fā)優(yōu)化方案
因?yàn)槲⒎?wù)之間互不影響,宕機(jī)不至于影響其他服務(wù);當(dāng)并發(fā)量超出預(yù)期,Docker部署快速擴(kuò)容;
分庫(kù)分表,r/w分離;
使用MQ異步修改庫(kù)存; - - - 這兩種治標(biāo)不治本
使用令牌桶+MQ異步修改庫(kù)存 ;- - -推薦方案
使用數(shù)據(jù)庫(kù)樂(lè)觀鎖(CAS鎖,此種方式有個(gè)問(wèn)題如:100庫(kù)存100用戶搶購(gòu),最終只有60個(gè)用戶秒殺成功,原因是當(dāng)未獲取CAS鎖時(shí),當(dāng)前請(qǐng)求失效,自旋則無(wú)此問(wèn)題,其實(shí)秒殺用戶很多,最終也會(huì)全部秒殺成功);
使用Redis實(shí)現(xiàn)分布式鎖;
使用令牌桶+MQ異步形式實(shí)現(xiàn)修改庫(kù)存(有一個(gè)用戶等待過(guò)程)
使用Redis的SETNX命令,key為用戶phone,并指定key過(guò)期時(shí)間,如10s
二、秒殺系統(tǒng)的實(shí)現(xiàn)
1. 秒殺頁(yè)面前端優(yōu)化方案(CDN內(nèi)容分發(fā))
1M寬帶等于多少Kbps?等于128KB/S,如果加載一個(gè)網(wǎng)頁(yè)含靜態(tài)資源需要640/KB,那么就需要5秒時(shí)間加載整個(gè)網(wǎng)頁(yè)。
靜態(tài)資源優(yōu)化方案
1.is/css/img實(shí)現(xiàn)壓縮減少帶寬的傳輸、將靜態(tài)資源放入第三方資源服務(wù)器中(七牛云、阿里OSS)等。
2.商品詳情頁(yè)面使用Nginx實(shí)現(xiàn)緩存,Lua+OpenResty實(shí)現(xiàn)商品詳情頁(yè)面的更新;也可以使用時(shí)間戳參數(shù)更新Nginx靜態(tài)資源緩存。
思路:可以給頁(yè)面表單提前生成隱藏域參數(shù),用戶提交表單后臺(tái)根據(jù)該參數(shù)判斷該表單是否已經(jīng)提交。
2. 基于MQ+庫(kù)存令牌桶實(shí)現(xiàn)異步修改庫(kù)存
秒殺搶購(gòu)修改庫(kù)存如何減少數(shù)據(jù)庫(kù)IO操作:
場(chǎng)景:在高并發(fā)情況下,如果突然有10萬(wàn)個(gè)不同用戶的請(qǐng)求進(jìn)行秒殺,但是商品的庫(kù)存數(shù)量只有100個(gè),那么這時(shí)候可能會(huì)出現(xiàn)10萬(wàn)個(gè)請(qǐng)求執(zhí)行修改秒殺庫(kù)存sql語(yǔ)句,這時(shí)候可能會(huì)出現(xiàn)數(shù)據(jù)庫(kù)訪問(wèn)壓力承受不了?
解決方案:讀寫分離,分庫(kù)分表,Redis緩存庫(kù)存等…但是這些方案都是治標(biāo)不治本,不管秒殺是否成功,每個(gè)請(qǐng)求都會(huì)對(duì)數(shù)據(jù)庫(kù)做讀寫操作,造成數(shù)據(jù)庫(kù)壓力增大。
最終解決方案:
提前生成100(庫(kù)存數(shù)量)個(gè)令牌,用戶獲取到令牌才能執(zhí)行修改庫(kù)存的sql語(yǔ)句。
總結(jié)
- 上一篇: 图书分类页面php,PHP开发简单图书借
- 下一篇: 电商秒杀系统设计思路和实现方法