如何設計一個秒殺系統

wangsys發表於2021-09-09

之前一直準備寫一篇關於秒殺系統設計的文章,但是因為涉及到的東西還是挺多的,拖延症發作一直沒抽空寫,最近閒了就把這個坑給填上,本文寫的方案是之前在電商公司工作的時候使用的大促秒殺方案。其實秒殺系統不單單適用於電商的搶購場景,其實一切涉及到大併發的場景都適合於使用該套秒殺系統方案,例如互金系統中的搶加息券什麼的也可以使用,整個方案中使用到的技術也是日常工作中經常用到的技術。

秒殺系統的難點

首先我們先看下秒殺場景的難點到底在哪?在秒殺場景中最大的問題在於容易產生大併發請求、產生超賣現象和效能問題,下面我們分別分析下下面這三個問題:

1)瞬時大併發:一提到秒殺系統給人最深刻的印象是超大的瞬時併發,這時你可以聯想到小米手機的搶購場景,在小米手機搶購的場景一般都會有10w+的使用者同時訪問一個商品頁面去搶購手機,這就是一個典型的瞬時大併發,如果系統沒有經過限流或者熔斷處理,那麼系統瞬間就會崩掉,就好像被DDos攻擊一樣;

2)超賣:秒殺除了大併發這樣的難點,還有一個所有電商都會遇到的痛,那就是超賣,電商搞大促最怕什麼?最怕的就是超賣,產生超賣了以後會影響到使用者體驗,會導致訂單系統、庫存系統、供應鏈等等,產生的問題是一系列的連鎖反應,所以電商都不希望超賣發生,但是在大併發的場景最容易發生的就是超賣,不同執行緒讀取到的當前庫存資料可能下個毫秒就被其他執行緒修改了,如果沒有一定的鎖庫存機制那麼庫存資料必然出錯,都不用上萬併發,幾十併發就可以導致商品超賣;

3)效能:當遇到大併發和超賣問題後,必然會引出另一個問題,那就是效能問題,如何保證在大併發請求下,系統能夠有好的效能,讓使用者能夠有更好的體驗,不然每個使用者都等幾十秒才能知道結果,那體驗必然是很糟糕的;

秒殺系統方案

對於上面提到的秒殺的問題,我們當時的架構是下面這樣的:

圖片描述

Screenshot 2018-05-24 14.58.41

從整個秒殺系統的架構其實和一般的網際網路系統架構本身沒有太多的不同,核心理念還是透過快取、非同步、限流來保證系統的高併發和高可用。下面從一筆秒殺交易的流程來描述下秒殺系統架構設計的要點:

1)對於大促時候的秒殺活動,一般運營會配置靜態的活動頁面,配置靜態活動頁面主要有兩個目的一方面是為了便於在各種社交媒體分發,另一方面是因為秒殺活動頁的流量是大促期間最大的,透過配置成靜態頁面可以將頁面釋出在公有云上動態的橫向擴充套件;

2)將秒殺活動的靜態頁面提前重新整理到CDN節點,透過CDN節點的頁面快取來緩解訪問壓力和公司網路頻寬,CDN上快取js、css和圖片;

3)將活動H5頁面部署在公有云的web  server上,使用公有云最大的好處就是能夠根據活動的火爆程度動態擴容而且成本較低,同時將訪問壓力隔離在公司系統外部;

4)在提供真正商品秒殺業務功能的app server上,需要進行交易限流、熔斷控制,防止因為秒殺交易影響到其他正常服務的提供,我們在限流和熔斷方面使用了hystrix,在核心交易的controller層透過hystrix進行交易併發限流控制,當交易流量超出我們設定的限流最大值時,會對新交易進行熔斷處理固定返回靜態失敗報文。

5)服務降級處理,除了上面講到的限流和熔斷控制,我們還設定了降級開關,對於首頁、購物車、訂單查詢、大資料等功能都會進行一定程度的服務降級,例如我們會對首頁原先動態生成的大資料頁面佈局降級為所有人看到的是一樣的頁面、購物車也會降級為不在一級頁面的tabbar上的購物車圖示上顯示商品數量、歷史訂單的查詢也會提供時間週期較短的查詢、大資料商品推薦也會提供一樣的商品推薦,透過這樣的降級處理能夠很好的保證各個系統在大促期間能夠正常的提供最基本的服務,保證使用者能夠正常下單完成付款。

6)上面介紹的都是如何保證能扛住高併發,下面介紹下整個方案中如何防止超賣現象的發生,我們日常的下單過程中防止超賣一般是透過在資料庫上實施樂觀鎖來完成,使用樂觀鎖雖然比for update這種悲觀鎖方式效能要好很多,但是還是無法滿足秒殺的上萬併發需求,我們的方案其實也很簡單實時庫存的扣減在快取中進行,非同步扣減資料庫中的庫存,保證快取中和資料庫中庫存的最終一致性。

在這個方案中我們使用的分散式快取是redis,使用了codis叢集方案穩定性和高可用方面還是比較有保證的,因為redis是單執行緒寫,所以也不用擔心執行緒安全的問題,redis自身就能夠保證資料的強一致性,在下單的事務中包含了實時扣減快取中的庫存和非同步傳送佇列,由佇列處理器再非同步從佇列中取出訂單根據訂單資訊扣減庫存系統資料庫中的商品數量。

總結

整個秒殺方案就介紹這麼多,其實整個的思路還是比較簡單的,也沒有特別複雜的地方,對於大部分公司的高併發場景還是適用的,並且比較容易實施上線,該方案對於我們當時每秒幾萬的併發場景是能夠扛住的,但是對於像小米、12306這些在高峰時動不動幾十萬使用者併發的場景,使用這樣的方案可能使用者體驗方面和系統服務方面就會存在一些問題了,對於每秒幾十萬併發的場景我們一般除了會在技術層面進行最佳化,更多的會透過其他一些業務手段來進行交易分流來分散整體的高併發訪問,秒殺方案就介紹到這裡,具體的實現這裡就不寫了,我相信跟著上面介紹的思路很容易就能將程式碼寫出來。



作者:monkey01
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2820243/,如需轉載,請註明出處,否則將追究法律責任。

相關文章