秒殺與其他業(yè)務(wù)最大的區(qū)別在于:秒殺的瞬間,(1)系統(tǒng)的并發(fā)量會非常的大(2)并發(fā)量大的同時肌稻,網(wǎng)絡(luò)的流量也會瞬間變大。
關(guān)于(2),最常用的辦法就是做頁面靜態(tài)化徘意,也就是常說的前后端分離,把靜態(tài)頁面直接緩存到用戶的瀏覽器端轩褐,所需要的數(shù)據(jù)從服務(wù)端接口動態(tài)獲取椎咧。這樣會大大節(jié)省網(wǎng)絡(luò)的流量,再加上CDN把介,一般不會有大問題勤讽。
關(guān)于(1),這里的核心問題就在于如何在大并發(fā)的情況下能保證DB能扛得住壓力拗踢,因為大并發(fā)的瓶頸在于DB脚牍。如果說請求直接從前端透傳到DB,顯然巢墅,DB是無法承受幾十萬上百萬甚至上千萬的并發(fā)量的诸狭。所以,我們能做的只能是減少對DB的訪問君纫,前端發(fā)出了100萬個請求驯遇,通過我們的處理,最終只有10個會訪問DB蓄髓,這樣就可以了叉庐!針對秒殺這種場景,因為秒殺商品的數(shù)量是有限的双吆,這種做法剛好適用眨唬!
那么具體是如何來減少DB的訪問呢会前?
假如:某個商品可秒殺的數(shù)量是10,那么在秒殺活動開始之前匾竿,把商品的ID和數(shù)量加載到緩存瓦宜,比如:Redis。服務(wù)端收到請求的時候岭妖,首先減一下Redis里面的數(shù)量临庇,如果數(shù)量減到0隨后的訪問直接返回秒殺失敗。也就是說昵慌,只有10個請求最終會去實際的請求DB假夺。
當然,如果我們的商品數(shù)比較多斋攀,1萬件商品參與秒殺已卷,1萬*10=10萬個并發(fā)去請求DB,DB的壓力還是會很大淳蔼,這里就用到另一個非常重要的組件:消息隊列侧蘸。我們不是把請求直接去訪問DB,而是先把請求寫到消息隊列鹉梨,做一個緩存讳癌,然后再去慢慢的更新數(shù)據(jù)庫。這樣做以后存皂,前端用戶的請求可能不會立即得到響應(yīng)是成功還是失敗晌坤,很可能得到的是一個排隊中的返回值,這個時候旦袋,需要客戶端再去服務(wù)端輪詢骤菠,因為我們不能保證一定就秒殺成功了。當服務(wù)端出隊猜憎,生成訂單以后娩怎,把用戶ID和商品ID寫到緩存中,來應(yīng)對客戶端的輪詢就可以了胰柑。
這樣處理以后截亦,我們的應(yīng)用是可以很簡單的進行分布式橫向擴展的,以應(yīng)對更大的并發(fā)柬讨。
當然崩瓤,秒殺系統(tǒng)還有很多要處理的事情:比如防刷限流、比如分布式Session等等踩官。
整體的思路大概就是這樣子的却桶,歡迎大家觀看我錄的一個視頻課程:http://coding.imooc.com/class/168.html