1. 程式人生 > 其它 >秒殺業務方案思路

秒殺業務方案思路

秒殺業務最大的業務特點,短時間內,高併發,大量讀請求,大量的寫請求。如果不經任何優化,直接將全部讀寫請求打到資料庫層,資料庫層由於鎖衝突,特別是熱點資料行鎖衝突,很容易造成死鎖,降低資料庫執行效率。而且流量很大的情況,很容易將會把資料庫壓死。資料庫層若掛了,如果再次啟動,很可能又會被大流量再次壓垮。

從系統的角度來看,在秒殺業務的情況下,我們要保護資料層的安全。

為了保證資料庫的安全,我們就要降低最後到達資料庫層讀寫流量,使其一直處於安全的情況下執行。

從讀寫方向,優化思路:

  • 降讀
  • 降寫

降低資料層讀請求,主要辦法就是加快取,資料優先讀取快取,快取不存在再從資料庫層讀取。快取解決辦法比較多,下面主要介紹降寫的處理辦法。

降低資料層寫請求,我們就必須在上游應用層過濾寫清求。

技術優化手段

假設我們的系統架構如下:

網站/APP---->站點接入應用------>後臺服務---->資料庫層

我們可以在這三層做優化,攔截寫請求,降低資料層寫壓力。

在網站/APP 層,我們可以使用 JS 等手段,防止使用者重複點選。

不過這種手段只能預防普通使用者,高階使用者可以通過抓包獲取請求介面,通過程式發起,繞開 JS。

所以我們需要在站點接入層通過計數的方式,防止同一使用者頻繁傳送請求。比如我們可以限制同一使用者每 5 秒,只有一次請求才有效,其餘請求返回請求速率過快。

站點層只能限制單一使用者,可以通過多使用者手段繞開這一限制。

等到寫請求到達服務層,服務層可以傳送到 MQ 佇列或者記憶體佇列,然後根據庫存數量,或者資料庫抗壓能力處理。

比如說某件商品庫存只有 2000 個,這時服務層現收到 2 w 個寫請求,全部發送到佇列中。假設資料庫層只能最大隻能處理 1000 個寫請求,那我們消費程式就拉取 1000 條訊息,真正進行資料寫請求。

寫入成功之後,再次消費訊息,直到庫存為 0 。這時剩下的訊息,都無需再執行資料庫的寫請求。

產品手段

除了上述的技術手段之外,我們還可以在產品設計方面減少寫請求。

我們可以在頁面使下單按鈕置灰,防止重複點選。

我們還可以頁面是不顯示庫存具體數量,只顯示庫存的是否還有,降低快取的淘汰率。

我們還可以將下單與支付流程分離,下單成功後,才能去支付。這時支付系統的壓力就很小很多。

相關問題

站點層服務壓力很大的處理方案

在我們上面的方案中,站點接入層需要計數過濾,壓力可能會很大。由於站點接入層一般都是無狀態應用,可以水平擴充套件。所以我們可以適當增加機器,增加處理能力。

另外,我們還可以設定一定閾值,等請求到達閾值之後,服務降級,拋棄後續請求。

計數問題

計數我們可以儲存在 Redis 中,如果 Redis 效能不夠,我們可以水平擴充套件,使用類似 Redis Cluster 方案。

Redis 吞吐量很大,如果害怕網路頻寬成為瓶頸,我們可以考慮不使用 Redis ,直接在記憶體中計數,不過這種方案就需要考慮資料一致性。

如果使用記憶體計數,同一使用者的請求就必須落在同一臺機器上。這裡的處理的方案我們可以在 Nginx 層使用 使用者 ID 切分,然後在分發到的站點接入層。

另外使用記憶體計數,我們降低資料的一致性與準確性,允許因業務重啟,導致記憶體的丟失的情況。

佇列非同步處理,瀏覽器/APP處理方式

1.在請求傳送到佇列中時,我們可以提前預分配一個訂單號,訊息傳送成功,將訂單號返回給頁面

2.瀏覽器/APP 拿到訂單號返回之後,跳轉到中間也,然後定時輪詢。頁面我們可以提示使用者,訂單正在排隊中,若重新整理將會再次進入排隊,防止使用者再次重新整理下單。

熱點隔離

秒殺系統設計的第一個原則就是將這種熱點資料隔離出來,不要讓1%的請求影響到另外的99%,隔離出來後也更方便對這1%的請求做針對性優化。針對秒殺我們做了多個層次的隔離:

業務隔離

把秒殺做成一種營銷活動,賣家要參加秒殺這種營銷活動需要單獨報名,從技術上來說,賣家報名後對我們來說就是已知熱點,當真正開始時我們可以提前做好預熱。其實這種方法比較噁心,也是現在某寶,某東經常做的,而且還有那種遊戲裡面做的也是這種形式。

系統隔離

系統隔離更多是執行時的隔離,可以通過分組部署的方式和另外99%分開。秒殺還申請了單獨的域名,目的也是讓請求落到不同的叢集中。 資料隔離。秒殺所呼叫的資料大部分都是熱資料,比如會啟用單獨cache叢集或MySQL資料庫來放熱點資料,目前也是不想0.01%的資料影響另外99.99%。

動靜分離

大家看一下圖一

這是把整個頁面Cache在使用者瀏覽器,這樣把90%的靜態資料快取在使用者端或者CDN上,當真正秒殺時使用者只需要點選特殊的按鈕“重新整理搶寶”即可,而不需要重新整理整個頁面,這樣只向服務端請求很少的有效資料,而不需要重複請求大量靜態資料。秒殺的動態資料和普通的詳情頁面的動態資料相比更少,效能也比普通的詳情提升3倍以上。所以“重新整理搶寶”這種設計思路很好地解決了不重新整理頁面就能請求到服務端最新的動態資料。

其實這種我發現也是用於解決高併發的一種手段,像如果要是很多培訓出來的同學的話,有做電商專案的可能會用到的,希望能給大家有一些好的啟發,如果能唬住面試官的話,那肯定能獲取一份不錯的offer