談談秒殺系統的落地方案
來自專欄架構棧4 人贊了文章
昨天的文章給秒殺系列開了一個頭,今天會集中講一下實現一個秒殺系統的思路和方案,不代表這就是最好的方案或者最佳實踐,而是希望通過這篇文章,能起到拋磚引玉的作用,希望有更佳的思路提供出來。
秒殺系統要解決的技術挑戰
1. 短時間內的超高訪問量對後台服務的衝擊。秒殺期間,來自外部請求產生的QPS會是平時的10~100倍。 2. 資料庫的讀寫壓力陡增。大量的並發寫,會造成資料庫的行鎖處於無法釋放的狀態,大量的線程排隊進而造成服務請求超時失敗。 3. 網路帶寬資源會因為秒殺被大量佔據掉。假設秒殺頁面的大小為150K,如果最大並發連接數為20000,那麼應用伺服器至少需要支持的帶寬>3G。
秒殺系統開發前的準備
1. 所有頁面的靜態資源走CDN,CSS, JS和圖片放入CDN後,利用遍布全國的CDN節點,降低帶寬和靜態伺服器的壓力,避免網路帶寬成為業務瓶頸。 2. 準備獨立的伺服器,秒殺系統單獨部署,包括使用單獨域名,避免秒殺業務對正常業務的系統的衝擊和影響。 3. 建立性能測試的環境,上線前根據本次秒殺的業務目標和流量預估,制定性能測試計劃,只有通過性能測試後,才能真正上線。
秒殺系統的架構設計
1. 前端的設計
在整個活動過程中,前端頁面應該是如下狀態:
秒殺開始前,秒殺按鈕灰掉為「未開始」,不可點擊。秒殺進行中,秒殺按鈕可以點擊下單。秒殺結束後,秒殺按鈕灰掉為「已結束」,不可點擊。
所以我們需要做以下幾件事:
1. 秒殺產品的介紹,詳情,參數等等,全部靜態化,切勿通過後台API查詢更新,減輕後端的壓力。
2. 用戶點擊「下單」後,按鈕置灰,禁止用戶重複提交請求,限制用戶在60秒之內只能提交一次請求。
3. 「下單」的URL在活動開始前不可露出或者生效,否則容易被使用工具繞過瀏覽器提前下單。導致活動還未開始,已經開始下單這個大黑洞。正確的做法是活動開始前,通過更新JS文件露出下單的URL。
4. 下單過程中,涉及到訂單參數的修改全部關掉,比如,購買的金額,產品的份額等等,降低訂單服務的壓力。
2. 服務層的設計
服務層的設計,如下圖所示:
- 確保所有服務的緩存是獨立分開,相互不影響。
- 按照昨天文章寫到的那樣,檢查用戶的身份和條件,將無效的用戶請求阻止在業務層之前。
- 所有讀請求全部走緩存,Redis or MemCached, 也可以考慮走讀庫,請注意流量的分配。
- 秒殺開始前,所有產品的屬性和庫存預載入到緩存中,秒殺過程中不主動更新資料庫,庫存數據延遲非同步更新。
- 對於訂單的寫請求,加緩存,並做請求隊列,每次只透過有限的寫請求去數據層,扣除庫存成功均成功再進行下一批訂單數據的更新,如果庫存不夠則隊列里的寫請求全部直接返回,儘可能阻止無效的請求穿透到數據層;
- 當瞬間秒殺產品庫存太大,造成的Redis寫暴增,可能造成線程阻塞最後寫超時對於如上的異常,添加一個秒殺開關,大量異常時開關關閉停止一切秒殺活動,以免造成更大的損失。
建立秒殺系統的監控
為了應對秒殺過程中的各種突發情況,我們還需要建立有效的監控手段來保障秒殺的過程。
- 監控Redis調用性能,主要是看讀和寫的性能兩個指標。
- 監控各個關鍵介面的運行情況,特別是下單介面的狀態,看是否有大量請求timeout或者異常的情況出現,關註失敗的訂單數,設置預警閾值。如果超過閾值,報警並採取緊急處理措施,例如關閉秒殺,進行服務降級。
- 監控資料庫的性能,密切關注訂單寫庫的執行狀態和讀庫的同步情況。
掃描二維碼或手動搜索微信公眾號【架構棧】: ForestNotes
歡迎轉載,帶上以下二維碼即可
點擊「閱讀原文」,所有【架構棧】近期的架構文章匯總
推薦閱讀:
※聰明女人靠什麼秒殺男人
※冬季街頭最搶鏡 秒殺路人視線
※八一八一聽就被秒殺的老歌
※唐僧的原型足以秒殺所有的冒險家!
※她擁有G奶女神之稱,身材秒殺柳岩,男朋友卻是一個小矮人