秒殺系統(tǒng)必須考慮的 3 個技術(shù)問題败徊!

[Java技術(shù)棧](javascript:void(0);) 1周前

image

來源:cnblogs.com/dreamworlds/p/5398468.html

1、并發(fā)隊列的選擇

Java的并發(fā)包提供了三個常用的并發(fā)隊列實現(xiàn)鸠删,分別是:ArrayBlockingQueue怯屉、ConcurrentLinkedQueue 和 LinkedBlockingQueue 。

ArrayBlockingQueue是初始容量固定的阻塞隊列附较,我們可以用來作為數(shù)據(jù)庫模塊成功競拍的隊列吃粒,比如有10個商品,那么我們就設(shè)定一個10大小的數(shù)組隊列拒课。

ConcurrentLinkedQueue使用的是CAS原語無鎖隊列實現(xiàn)徐勃,是一個異步隊列,入隊的速度很快早像,出隊進行了加鎖僻肖,性能稍慢。

LinkedBlockingQueue也是阻塞的隊列卢鹦,入隊和出隊都用了加鎖臀脏,當隊空的時候線程會暫時阻塞。

在請求預(yù)處理階段冀自,由于我們的系統(tǒng)入隊需求要遠大于出隊需求揉稚,一般不會出現(xiàn)隊空的情況,所以我們可以選擇ConcurrentLinkedQueue來作為我們的請求隊列實現(xiàn)凡纳。

2窃植、請求接口的合理設(shè)計

一個秒殺或者搶購頁面,通常分為2個部分荐糜,一個是靜態(tài)的HTML等內(nèi)容巷怜,另一個就是參與秒殺的Web后臺請求接口葛超。

通常靜態(tài)HTML等內(nèi)容,是通過CDN的部署延塑,一般壓力不大绣张,核心瓶頸實際上在后臺請求接口上。這個后端接口关带,必須能夠支持高并發(fā)請求侥涵,同時,非常重要的一點宋雏,必須盡可能“快”芜飘,在最短的時間里返回用戶的請求結(jié)果。

為了實現(xiàn)盡可能快這一點磨总,接口的后端存儲使用內(nèi)存級別的操作會更好一點嗦明。仍然直接面向MySQL之類的存儲是不合適的,如果有這種復(fù)雜業(yè)務(wù)的需求蚪燕,都建議采用異步寫入娶牌。

image

當然,也有一些秒殺和搶購采用“滯后反饋”馆纳,就是說秒殺當下不知道結(jié)果诗良,一段時間后才可以從頁面中看到用戶是否秒殺成功。

但是鲁驶,這種屬于“偷懶”行為鉴裹,同時給用戶的體驗也不好,容易被用戶認為是“暗箱操作”灵嫌。推薦:秒殺系統(tǒng)設(shè)計的 5 個要點壹罚。

3葛作、高并發(fā)下的數(shù)據(jù)安全

我們知道在多線程寫入同一個文件的時候寿羞,會存現(xiàn)“線程安全”的問題(多個線程同時運行同一段代碼,如果每次運行結(jié)果和單線程運行的結(jié)果是一樣的赂蠢,結(jié)果和預(yù)期相同绪穆,就是線程安全的)。

如果是MySQL數(shù)據(jù)庫虱岂,可以使用它自帶的鎖機制很好的解決問題玖院,但是,在大規(guī)模并發(fā)的場景中第岖,是不推薦使用MySQL的难菌。秒殺和搶購的場景中,還有另外一個問題蔑滓,就是“超發(fā)”郊酒,如果在這方面控制不慎遇绞,會產(chǎn)生發(fā)送過多的情況。

我們也曾經(jīng)聽說過燎窘,某些電商搞搶購活動摹闽,買家成功拍下后,商家卻不承認訂單有效褐健,拒絕發(fā)貨付鹿。這里的問題,也許并不一定是商家奸詐蚜迅,而是系統(tǒng)技術(shù)層面存在超發(fā)風(fēng)險導(dǎo)致的舵匾。

超發(fā)的原因

假設(shè)某個搶購場景中,我們一共只有100個商品谁不,在最后一刻纽匙,我們已經(jīng)消耗了99個商品,僅剩最后一個拍谐。

這個時候烛缔,系統(tǒng)發(fā)來多個并發(fā)請求,這批請求讀取到的商品余量都是99個轩拨,然后都通過了這一個余量判斷践瓷,最終導(dǎo)致超發(fā)。(同文章前面說的場景)

image

在上面的這個圖中亡蓉,就導(dǎo)致了并發(fā)用戶B也“搶購成功”晕翠,多讓一個人獲得了商品。這種場景砍濒,在高并發(fā)的情況下非常容易出現(xiàn)淋肾。

悲觀鎖思路

解決線程安全的思路很多,可以從“悲觀鎖”的方向開始討論爸邢。

悲觀鎖樊卓,也就是在修改數(shù)據(jù)的時候,采用鎖定狀態(tài)杠河,排斥外部請求的修改碌尔。遇到加鎖的狀態(tài),就必須等待券敌。

image

雖然上述的方案的確解決了線程安全的問題唾戚,但是,別忘記待诅,我們的場景是“高并發(fā)”叹坦。也就是說,會很多這樣的修改請求卑雁,每個請求都需要等待“鎖”募书,某些線程可能永遠都沒有機會搶到這個“鎖”轧钓,這種請求就會死在那里。

同時锐膜,這種請求會很多毕箍,瞬間增大系統(tǒng)的平均響應(yīng)時間,結(jié)果是可用連接數(shù)被耗盡道盏,系統(tǒng)陷入異常而柑。推薦:并發(fā)控制--悲觀鎖和樂觀鎖詳解

FIFO隊列思路

那好荷逞,那么我們稍微修改一下上面的場景媒咳,我們直接將請求放入隊列中的,采用FIFO(First Input First Output种远,先進先出)涩澡,這樣的話,我們就不會導(dǎo)致某些請求永遠獲取不到鎖坠敷∶钔看到這里,是不是有點強行將多線程變成單線程的感覺哈膝迎。

image

然后粥帚,我們現(xiàn)在解決了鎖的問題,全部請求采用“先進先出”的隊列方式來處理限次。那么新的問題來了芒涡,高并發(fā)的場景下,因為請求很多卖漫,很可能一瞬間將隊列內(nèi)存“撐爆”费尽,然后系統(tǒng)又陷入到了異常狀態(tài)。

或者設(shè)計一個極大的內(nèi)存隊列羊始,也是一種方案旱幼,但是,系統(tǒng)處理完一個隊列內(nèi)請求的速度根本無法和瘋狂涌入隊列中的數(shù)目相比店枣。

也就是說速警,隊列內(nèi)的請求會越積累越多,最終Web系統(tǒng)平均響應(yīng)時候還是會大幅下降鸯两,系統(tǒng)還是陷入異常。

樂觀鎖思路

這個時候长豁,我們就可以討論一下“樂觀鎖”的思路了钧唐。樂觀鎖,是相對于“悲觀鎖”采用更為寬松的加鎖機制匠襟,大都是采用帶版本號(Version)更新钝侠。

實現(xiàn)就是该园,這個數(shù)據(jù)所有請求都有資格去修改,但會獲得一個該數(shù)據(jù)的版本號帅韧,只有版本號符合的才能更新成功里初,其他的返回搶購失敗。推薦:并發(fā)控制--悲觀鎖和樂觀鎖詳解忽舟。

這樣的話双妨,我們就不需要考慮隊列的問題,不過叮阅,它會增大CPU的計算開銷刁品。但是,綜合來說浩姥,這是一個比較好的解決方案挑随。

image

有很多軟件和服務(wù)都“樂觀鎖”功能的支持,例如Redis中的watch就是其中之一勒叠。通過這個實現(xiàn)兜挨,我們保證了數(shù)據(jù)的安全。


個人論點:

      是不是可以采用降級的方案眯分,若是有100個商品參與購買暑劝,則將前100個請求放入隊列,隊列滿了之后颗搂,直接返回搶購失敗担猛,進入的100個線程進行下一步操作,這樣系統(tǒng)性能不會崩潰丢氢,并且不會發(fā)生超發(fā)情況傅联。當然剩余商品數(shù)可以放入內(nèi)存,直接內(nèi)存中計算疚察,成功后直接返回顯示搶購成功蒸走,然后異步從數(shù)據(jù)庫扣減庫存。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末貌嫡,一起剝皮案震驚了整個濱河市比驻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岛抄,老刑警劉巖别惦,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夫椭,居然都是意外死亡掸掸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扰付,“玉大人堤撵,你說我怎么就攤上這事∮疠海” “怎么了实昨?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盐固。 經(jīng)常有香客問我荒给,道長,這世上最難降的妖魔是什么闰挡? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任锐墙,我火速辦了婚禮,結(jié)果婚禮上长酗,老公的妹妹穿的比我還像新娘溪北。我一直安慰自己,他們只是感情好夺脾,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布之拨。 她就那樣靜靜地躺著,像睡著了一般咧叭。 火紅的嫁衣襯著肌膚如雪蚀乔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天菲茬,我揣著相機與錄音吉挣,去河邊找鬼。 笑死婉弹,一個胖子當著我的面吹牛睬魂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镀赌,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氯哮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了商佛?” 一聲冷哼從身側(cè)響起喉钢,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎良姆,沒想到半個月后肠虽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡歇盼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年舔痕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豹缀。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡伯复,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出邢笙,到底是詐尸還是另有隱情啸如,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布氮惯,位于F島的核電站叮雳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏妇汗。R本人自食惡果不足惜帘不,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杨箭。 院中可真熱鬧寞焙,春花似錦、人聲如沸互婿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽慈参。三九已至呛牲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驮配,已是汗流浹背娘扩。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留壮锻,地道東北人琐旁。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像躯保,于是被迫代替她去往敵國和親旋膳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容