秒殺系統架構如何設計之我見

風吹白楊樹發表於2019-02-16

秒殺背景

電商中為了吸引顧客、聚集人氣,經常會策劃一些秒殺活動。活動中售賣的商品,要麼價格遠低於市場價格,要麼比較稀缺(如一些新發布的商品)。這些商品電商一般都會限量、限時銷售。無疑這些商品對消費者的誘惑力是巨大的,消費者蜂擁而來,往往幾秒鐘就可以將商品搶購一空。而對於電商系統來說可能更多的是考驗。

秒殺痛點

首先,秒殺的場景決定了秒殺是一場速度的比拼,也就是俗話說的“手快有、手慢無”。大家都爭著在活動開始後,第一時間將商品搶到,完成下單。因此秒殺活動開始的一瞬間會有大量的流量湧入,幾倍、甚至於十幾倍的流量對系統的衝擊不可謂不大。如果系統沒有足夠的capacity或應對措施,很可能就被瞬時高流量給壓垮了。

其次,突如其來的高流量,給系統各個模組都來了一連串的壓力,系統可能會因此變慢,而且可能會彼此影響,影響可用性。比如:資料庫更新同一個商品庫存,需對同一行記錄加鎖,隨著併發的壓力逐漸增大,資料庫更新的效能是逐漸下降的。從而引起提供庫存service的應用服務效能下降,連鎖的影響到下單service的效能,最終反饋到消費者的可能就是整個網站購物流程效能差、響應慢。而面對響應慢的系統,很多消費者可能採取反覆重新整理,多次嘗試,這無疑又增大了對系統的壓力。

還有,上述種種給消費者帶來的往往是體驗上的痛苦。如:網站響應慢,點選搶購按鈕沒反應。好不容易可以操作了,卻發現秒殺活動已經結束,消費者的參與感比較差。久而久之,可能就對此類活動失去了興趣。

設計理念

分層限流:將壓力盡量集中在前端,減少資料庫、伺服器的壓力
非同步處理:非同步處理防止阻塞。
可用性:高可用雙活。
使用者體驗:隱藏購買地址。
分離:主站分離。

技術攻關

短時間內的大訪問量對現有網站業務造成的衝擊。

秒殺是一個網站營銷的一個附加活動,時間短,併發量大。

如果和網站原有應用部署在一起,必然會對現有業務造成衝擊,稍有不慎可能導致整個網站癱瘓。

高併發下對伺服器資料庫造成的極大負載壓力。

使用者秒殺開始前,通過不斷重新整理瀏覽器來保證不會錯過秒殺活動。

頻繁的訪問程式、資料庫會對應用伺服器和資料庫伺服器造成負載壓力。

網路頻寬的問題比超過平時好多倍。

如果秒殺頁面的大小為200K,如果最大併發數為10000次,那麼需要的網路和伺服器頻寬是2G(200K×10000)。

這些網路頻寬是因為秒殺活動新增的,超過網站平時使用的頻寬。

避免直接下單。

秒殺的遊戲規則是到了秒殺才能開始對商品下單購買,在此時間點之前,只能瀏覽資訊不可下單。

而下單頁面也是一個普通的URL,如果得到這個URL,不用等到秒殺開始就可以下單了。

應對策略

秒殺系統獨立部署

為了避免短時間內的大訪問量對現有網站業務造成的衝擊,可以將秒殺系統獨立部署。

如果需要還可以使用獨立域名,使其與網站完全隔離。

即使秒殺系統崩潰了,也不會對網站造成影響。

秒殺商品頁面靜態化

將商品描述、引數、詳情,全部寫到一個靜態頁面,不用進行程式的邏輯處理,不需訪問資料庫。

不用部署動態的伺服器和資料庫伺服器。

租借秒殺活動的網路頻寬

因為秒殺新增的網路頻寬,必須和運營商重新購買或租借頻寬。

為了減輕伺服器的壓力,需要將秒殺商品頁面快取在CDN,同樣CDN伺服器也需要臨時租借頻寬。

動態生成隨機下單頁面的URL

為了避免使用者直接訪問下單URL,需要將URL動態化,用隨機數作為引數,只能秒殺開始的時候才生成。

架構設計

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

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

如果頁面是動態生成的,每次重新整理都要請求伺服器,那麼勢必造成服務端的負載壓力。

如果頁面是靜態頁面的話,可以將頁面快取在CDN,反向代理伺服器上,甚至使用者瀏覽器上。

但是這樣,秒殺開始時,使用者重新整理頁面,根本請求不到應用伺服器。

解決方案:

使用JS指令碼控制,在頁面中引用一個JS檔案(檔案極小),但是該檔案不要被快取。

該JS的作用是,包含秒殺開始標誌,修改樣式,生成下單頁面的URL及隨機引數。

該JS檔案不被快取的做法:xxx.js?v=隨機數。

會有一臺伺服器進行監控(定時上下架):

當秒殺活動開始時推送該檔案。

當秒殺活動結束時推送檔案,標示結束標誌,修改樣式。

詳情:2018-01-27 20:00 實戰構建PHP千萬級PV秒殺系統 講堂

相關文章