天天看點

秒殺系統解決方案

一、秒殺一般會帶來2個問題:

1、高并發

比較火熱的秒殺線上人數都是10w起的,如此之高的線上人數對于網站架構從前到後都是一種考驗。

2、超賣

任何商品都會有數量上限,如何避免成功下訂單買到商品的人數不超過商品數量的上限,這是每個搶購活動都要面臨的難題。

二、如何解決?

1.架構層面:

秒殺架構設計原則:

  • 盡量将請求攔截在系統上遊
  • 讀多寫少的常用多使用緩存
  • 擴容加機器
  • 系統隔離  

為了避免短時間内的大通路量對現有網站業務造成的沖擊,可以将秒殺系統獨立部署。系統隔離更多是運作時的隔離,可以通過分組部署的方式和另外99%分開。秒殺還申請了單獨的域名,目的也是讓請求落到不同的叢集中。即使秒殺系統崩潰了,也不會對網站造成影響。

  • 資料隔離

将即将被秒殺的熱資料維護到redis。秒殺所調用的資料大部分都是熱資料,比如會啟用單獨cache叢集或MySQL資料庫來放熱點資料,目前也是不想0.01%的資料影響另外99.99%。

  • 減庫存操作

一種是拍下減庫存 另外一種是付款減庫存;目前采用的“拍下減庫存”的方式,拍下就是一瞬間的事,對使用者體驗會好些。

2.産品層面:

  • 控制秒殺商品頁面搶購按鈕的可用/禁用。

購買按鈕隻有在秒殺開始的時候才能點亮,在此之前是灰色的,顯示活動未開始。

  • 增加了秒殺答題,基于時間分片削峰

秒殺答題一個很重要的目的是為了防止秒殺器。還有一個重要的功能,就是把峰值的下單請求給拉長了,從以前的1s之内延長到2~10s左右,請求峰值基于時間分片了,這個時間的分片對服務端處理并發非常重要,會減輕很大壓力,另外由于請求的先後,靠後的請求自然也沒有庫存了,也根本到不了最後的下單步驟,是以真正的并發寫就非常有限了。其實這種設計思路目前也非常普遍,如支付寶的“咻一咻”已及微信的搖一搖。

  • 秒殺頁面設計簡化

秒殺場景業務需求與一般購物不同,使用者更在意的是能夠搶到商品而不是使用者體驗。是以秒殺商品頁面應盡可能簡單并且拍下後位址等個人資訊應該使用預設資訊,減輕秒殺進行時系統負載,若有更改可以在秒殺結束後進行更改。

3.前端層面

  • 靜态化以及頁面緩存

将頁面能夠靜态的部分都靜态化,并将靜态頁面緩存于CDN,以及反向代理伺服器,可能還要臨時租借伺服器。 利用 頁面靜态化、資料靜态化,反向代理等方法可以避免帶寬和sql壓力 ,但是随之而來一個問題,頁面搶單按鈕也不會重新整理了,可以把 js 檔案單獨放在js伺服器上,由另外一台伺服器寫 定時任務 來控制js 推送。 另外還有一個問題,js檔案會被大部分浏覽器緩存,我們可以使用xxx.js?v=随機數 的方式來避免js被緩存。

  • 限流(反作弊)
  1. 針對同一個使用者id來實作,前端js控制一個用戶端幾秒之内隻能發送同一個請求,後端校驗同一個uid在幾秒之内傳回同一個頁面
  2. 針對同一個ip來實作,進行ip檢測,同一個ip幾秒之内發送請求或者隻傳回同一個頁面
  3. 針對多使用者多ip來實作,依靠資料分析
  4. 為了避免使用者直接通路下單頁面URL,需要将改URL動态化,即使秒殺系統的開發者也無法在秒殺開始前通路下單頁面的URL。辦法是在下單頁面URL加入由伺服器端生成的随機數作為參數,在秒殺開始的時候才能得到

4.後端層面

  • 加入緩存redis:

因為秒殺是典型的讀多寫少的場景,适合操作記憶體而非操作硬碟;緩存工具redis本身的操作是保證原子性的,是以可以保證請求了redis的寫的操作的線程安全性。

  • 加入消息隊列,利用隊列進行削峰:

将使用者請求放置于一個或多個隊列中,隊列中元素總和等于該商品庫存總和,未進入隊列的請求均失敗。利用多線程輪詢分别從一個或多個隊列中取出使用者請求。操作redis進行減庫存操作,成功減庫存之後傳回成功,并将使用者資訊與商品資訊存入另一個隊列當中,進行生成訂單的操作。利用兩個隊列異步處理業務減輕秒殺高峰時期伺服器負載。

  • 程式計數器:

隊列與緩存為了保證請求redis的次數不超過總的庫存量,利用一個程式計數器來這一點。程式計數器用JUC包下原子類可以實作。

  • 分布式鎖

分布式情況下可以利用分布式鎖來解決任務每次隻能由一次服務來執行且不能重複執行。

分布式鎖的實作:zk、redis

分布式鎖的優化:先考慮是否可以去鎖,然後考慮盡可能多用樂觀鎖,少用悲觀鎖。這裡有一個問題,樂觀鎖如果每一次都會有并發沖突的話性能反而不如悲觀鎖,那麼難道真的多用樂觀鎖性能會比悲觀鎖高嗎?選舉考慮ha,比如心跳檢測。

  • 5.分布式去鎖方案

利用叢集并發加入隊列,選舉隊列處理服務單點執行,這樣可以保證并發實作和加鎖一樣的并發量但不會影響性能。

總結

  • 架構:擴容、業務分離、資料分離
  • 産品:下單按鈕控制、秒殺答題削峰、簡化頁面設計
  • 前端:限流(反作弊)、靜态化以及頁面緩存
  • 後端:記憶體資料庫 ,消息隊列、程式計數器、分布式鎖