秒殺系統的原則和注意項

程序员半支烟發表於2024-10-08

做任何技術方案都需要結合當時的業務場景、資金情況、使用者體量等維度綜合考慮,沒有最好的技術方案,只有最合適的技術方案。

做秒殺方案亦是如此,秒殺活動經常會引發高併發、系統當機和庫存超賣的棘手問題,作為開發者,我們該如何在保證系統穩定性的同時,防止業務風險呢?

本篇聊聊秒殺方案的幾個原則和注意點,腦圖見文末。

1、原則

縱觀多種秒殺方案,沒有相同的,但是這些方案都遵守了相同的原則。具體原則如下:

1.1、保護資料庫

秒殺場景下,一定要優先保護資料庫,這是重中之重。一旦資料庫當機,那系統徹底癱瘓,會給業務和口碑造成損失。保護資料庫要注意如下幾點:

  • 在應用層需要將不合格的請求全部攔截,避免邏輯觸達到資料庫。
  • 評估併發數,QPS等,給應用設定合理的資料庫連線池數量,避免將資料庫的連線耗盡。
  • 監控資料庫,觀測資料庫的CPU、記憶體等壓力,觀測慢SQL等,一旦出現問題,及時作出響應。

1.2、保護應用系統

應用系統也是要保護的物件,不管是單體還是微服務,系統儘量不當機。保護系統要注意這幾點:

  • 如果有條件的話,將秒殺系統的BFF層做成獨立的服務,這樣就算本服務掛了,也不影響別的服務。
  • 評估秒殺活動的訪問量,適當擴大部分微服務的負載數量,從而提高系統的響應能力。

1.3、提前退出

秒殺系統一旦對外開放,肯定會招來不少羊毛黨,甚至惡意攻擊。所以,在處理邏輯時,一定要做前置校驗,一旦發現非法請求,直接中斷。

如果有條件的話,也要做一些攻擊型測試和壓力測試,看看能否攔住非法請求,看看系統能否承受住壓力。

1.4、不超賣

秒殺場景下的商品,一般都是賠本賺吆喝,真的是賣一單虧一單。一般秒殺的商品、價格、庫存,都是公司的運營和管理層溝通確認的結果。

為了將虧損控制在合理的範圍,要嚴格按照既定的庫存去售賣,一定不能出現超賣的情況。

2、前端主要注意點

秒殺場景下,前端有一些注意點,如下:

  • 頁面靜態化:不管是在PC、H5、小程式還是APP,頁面儘量靜態化,能走快取的走快取,儘量少的去請求介面。
  • CDN:將涉及到的js、圖片、html等靜態資源,提前刷到CDN中,加快訪問速度。
  • 從快取讀取資料:秒殺場景下用到的介面要和常規介面區分開,秒殺場景下的介面儘量是從Redis快取中讀取資料,然後響應給前端。前端也需要判斷哪些資料可以存入前端快取中,避免下次重複調介面獲取。
  • 前端做攔截:前端頁面也要做一些攔截動作,過濾非法請求。雖然作用不大,只防君子不防小人,但是也要做。一切能提前攔截掉非法請求的動作,都要做。

3、後端主要注意點

後端的注意事項較多,大致如下:

  • 彈性增加伺服器:根據自身的整體部署情況,適當擴大負載。比如混合雲部署的方式,可以按需臨時租用幾臺雲廠商的雲伺服器,等活動結束立馬釋放雲伺服器,這樣成本最小。
  • 限流和降級:不管是在秒殺場景,還是其餘場景,保護系統的手段就是限流、降級、熔斷。不管擱在什麼時候,都是這三板斧。
  • 前置校驗:前置校驗可以最大程度的攔住非法請求。比如校驗惡意的重複IP、校驗使用者的重複下單、校驗庫存等等。
  • 快取預熱:對於秒殺的商品資訊和庫存,需要提前做快取預熱,比如將資料提前刷到Redis快取中。
  • 定時任務
    • 及時釋放庫存:一般場景下,可能半小時才會取消未支付的訂單。但在秒殺場景下,由於庫存有限,避免惡意佔庫存,所以允許訂單未支付的時間就要減少,比如3分鐘。這種場景下,可以用定時任務及時取消訂單,或者,採用訊息佇列的定時訊息方案(比如RocketMQ的延遲訊息)。
    • 校準快取的庫存:下單會佔用庫存,取消訂單會釋放庫存。如果庫存預熱到了Redis,則需要有個定時任務去校準Redis裡的庫存數量。
  • 下單和減庫存
    • 樂觀鎖減庫存:更新資料庫裡的庫存數量時,一定要使用樂觀鎖方案去避免超賣,類似update ttt set stock = xxx where product_id = yyy and stock = zzz;
    • 同步或非同步:在走完前置邏輯後,則會進入到下單和減庫存邏輯,此時,可以用同步方式直接呼叫,也可以用非同步丟入到MQ的方式。具體採用哪種方式,需要根據系統的吞吐量去做評估。

4、總結

本文主要聊了秒殺方案的幾個原則和前後端注意事項。方案千千萬,原則就這麼幾個。最後,貼上一張腦圖方便記憶。

本篇完結!歡迎 關注、加V(yclxiao)交流、全網可搜(程式設計師半支菸)

原文連結:https://mp.weixin.qq.com/s/EK_j7EyIEpz_YPJb8w1jsw

相關文章