秒殺背景
電商中為了吸引顧客、聚集人氣,經常會策劃一些秒殺活動。活動中售賣的商品,要麼價格遠低於市場價格,要麼比較稀缺(如一些新發布的商品)。這些商品電商一般都會限量、限時銷售。無疑這些商品對消費者的誘惑力是巨大的,消費者蜂擁而來,往往幾秒鐘就可以將商品搶購一空。而對於電商系統來說可能更多的是考驗。
秒殺痛點
首先,秒殺的場景決定了秒殺是一場速度的比拼,也就是俗話說的“手快有、手慢無”。大家都爭著在活動開始後,第一時間將商品搶到,完成下單。因此秒殺活動開始的一瞬間會有大量的流量湧入,幾倍、甚至於十幾倍的流量對系統的衝擊不可謂不大。如果系統沒有足夠的capacity或應對措施,很可能就被瞬時高流量給壓垮了。
其次,突如其來的高流量,給系統各個模組都來了一連串的壓力,系統可能會因此變慢,而且可能會彼此影響,影響可用性。比如:資料庫更新同一個商品庫存,需對同一行記錄加鎖,隨著併發的壓力逐漸增大,資料庫更新的效能是逐漸下降的。從而引起提供庫存service的應用服務效能下降,連鎖的影響到下單service的效能,最終反饋到消費者的可能就是整個網站購物流程效能差、響應慢。而面對響應慢的系統,很多消費者可能採取反覆重新整理,多次嘗試,這無疑又增大了對系統的壓力。
還有,上述種種給消費者帶來的往往是體驗上的痛苦。如:網站響應慢,點選搶購按鈕沒反應。好不容易可以操作了,卻發現秒殺活動已經結束,消費者的參與感比較差。久而久之,可能就對此類活動失去了興趣。
設計理念
分層限流:將壓力盡量集中在前端,減少資料庫、伺服器的壓力
非同步處理:非同步處理防止阻塞。
可用性:高可用雙活。
使用者體驗:隱藏購買地址。
分離:主站分離。
技術攻關
短時間內的大訪問量對現有網站業務造成的衝擊。
秒殺是一個網站營銷的一個附加活動,時間短,併發量大。
如果和網站原有應用部署在一起,必然會對現有業務造成衝擊,稍有不慎可能導致整個網站癱瘓。
高併發下對伺服器資料庫造成的極大負載壓力。
使用者秒殺開始前,通過不斷重新整理瀏覽器來保證不會錯過秒殺活動。
頻繁的訪問程式、資料庫會對應用伺服器和資料庫伺服器造成負載壓力。
網路頻寬的問題比超過平時好多倍。
如果秒殺頁面的大小為200K,如果最大併發數為10000次,那麼需要的網路和伺服器頻寬是2G(200K×10000)。
這些網路頻寬是因為秒殺活動新增的,超過網站平時使用的頻寬。
避免直接下單。
秒殺的遊戲規則是到了秒殺才能開始對商品下單購買,在此時間點之前,只能瀏覽資訊不可下單。
而下單頁面也是一個普通的URL,如果得到這個URL,不用等到秒殺開始就可以下單了。
應對策略
秒殺系統獨立部署
為了避免短時間內的大訪問量對現有網站業務造成的衝擊,可以將秒殺系統獨立部署。
如果需要還可以使用獨立域名,使其與網站完全隔離。
即使秒殺系統崩潰了,也不會對網站造成影響。
秒殺商品頁面靜態化
將商品描述、引數、詳情,全部寫到一個靜態頁面,不用進行程式的邏輯處理,不需訪問資料庫。
不用部署動態的伺服器和資料庫伺服器。
租借秒殺活動的網路頻寬
因為秒殺新增的網路頻寬,必須和運營商重新購買或租借頻寬。
為了減輕伺服器的壓力,需要將秒殺商品頁面快取在CDN,同樣CDN伺服器也需要臨時租借頻寬。
動態生成隨機下單頁面的URL
為了避免使用者直接訪問下單URL,需要將URL動態化,用隨機數作為引數,只能秒殺開始的時候才生成。
架構設計
如何控制秒殺商品頁面搶購按鈕的可用/禁用。
購買按鈕只有在秒殺開始的時候才能點亮,在此之前是灰色的,顯示活動未開始。
如果頁面是動態生成的,每次重新整理都要請求伺服器,那麼勢必造成服務端的負載壓力。
如果頁面是靜態頁面的話,可以將頁面快取在CDN,反向代理伺服器上,甚至使用者瀏覽器上。
但是這樣,秒殺開始時,使用者重新整理頁面,根本請求不到應用伺服器。
解決方案:
使用JS指令碼控制,在頁面中引用一個JS檔案(檔案極小),但是該檔案不要被快取。
該JS的作用是,包含秒殺開始標誌,修改樣式,生成下單頁面的URL及隨機引數。
該JS檔案不被快取的做法:xxx.js?v=隨機數。
會有一臺伺服器進行監控(定時上下架):
當秒殺活動開始時推送該檔案。
當秒殺活動結束時推送檔案,標示結束標誌,修改樣式。