1. 程式人生 > >高併發-秒殺流程

高併發-秒殺流程

秒殺系統解決高併發?

瀏覽器端(js):

  • 頁面靜態化:將活動頁面上的所有可以靜態的元素全部靜態化,做圖片伺服器分離,並儘量減少動態元素。通過CDN來抗峰值。
  • 禁止重複提交:使用者提交之後按鈕置灰,禁止重複提交
  • 使用者限流:在某一時間段內只允許使用者提交一次請求,比如可以採取IP限流

專案後端方案

1、web層

如果請求過多,判定web伺服器的壓力過大,增加前端的web伺服器,做負載均衡

2、服務層

如果請求的靜態頁面不卡了,但是請求的動態資料還是卡,說明mysql處理的請求太多了,即當秒殺的使用者量很大時,即使每個使用者只有一個請求,到服務層的請求數量還是很大。比如我們有100W使用者同時搶100臺手機,服務層併發請求壓力很大。這時可採用以下兩種辦法:

  1. 採用訊息佇列快取請求:既然服務層知道庫存只有100臺手機,那完全沒有必要把100W個請求都傳遞到資料庫啊,那麼可以先把這些請求都寫到訊息佇列快取一下,資料庫層訂閱訊息減庫存,減庫存成功的請求返回秒殺成功,失敗的返回秒殺結束。
  2. 利用快取應對寫請求:快取也是可以應對寫請求的,比如我們就可以把資料庫中的庫存資料轉移到Redis快取中,所有減庫存操作都在Redis中進行,然後再通過後臺程序把Redis中的使用者秒殺請求同步到資料庫中。

3、資料庫層

資料庫層是最脆弱的一層,一般在應用設計時在上游就需要把請求攔截掉,資料庫層只承擔“能力範圍內”的訪問請求,所以,上面通過在服務層引入佇列或快取,讓最底層的資料庫高枕無憂。若是還是不行,則資料庫也可以做主從,讀寫分離增加其能力範圍內的查詢。

案例:利用訊息中介軟體和快取實現簡單的秒殺系統

Redis是一個分散式快取系統,支援多種資料結構,我們可以利用Redis輕鬆實現一個強大的秒殺系統。

我們可以採用Redis 最簡單的key-value資料結構,用一個原子型別的變數值(AtomicInteger)作為key,把使用者id作為value,庫存數量便是原子變數的最大值。對於每個使用者的秒殺,我們使用 RPUSH key value插入秒殺請求, 當插入的秒殺請求數達到上限時,停止所有後續插入。

然後我們可以在臺啟動多個工作執行緒,使用 LPOP key 讀取秒殺成功者的使用者id,然後再操作資料庫做最終的下訂單減庫存操作。