當前位置:才華齋>職業>系統架構師>

秒殺系統架構分析

系統架構師 閱讀(2.36W)

所謂"秒殺",就是網路賣家釋出一些超低價格的商品,所有買家在同一時間網上搶購的一種銷售方式。下面整理了關於秒殺系統架構分析的文章,歡迎大家閱讀!

秒殺系統架構分析

  1 秒殺業務分析

正常電子商務流程

(1)查詢商品;(2)建立訂單;(3)扣減庫存;(4)更新訂單;(5)付款;(6)賣家發貨

秒殺業務的特性

(1)低廉價格;(2)大幅推廣;(3)瞬時售空;(4)一般是定時上架;(5)時間短、瞬時併發量高;

  2 秒殺技術挑戰

假設某網站秒殺活動只推出一件商品,預計會吸引1萬人參加活動,也就說最大併發請求數是10000,秒殺系統需要面對的技術挑戰有:

對現有網站業務造成衝擊

秒殺活動只是網站營銷的一個附加活動,這個活動具有時間短,併發訪問量大的特點,如果和網站原有應用部署在一起,必然會對現有業務造成衝擊,稍有不慎可能導致整個網站癱瘓。

解決方案:將秒殺系統獨立部署,甚至使用獨立域名,使其與網站完全隔離。

高併發下的應用、資料庫負載

使用者在秒殺開始前,通過不停重新整理瀏覽器頁面以保證不會錯過秒殺,這些請求如果按照一般的網站應用架構,訪問應用伺服器、連線資料庫,會對應用伺服器和資料庫伺服器造成負載壓力。

解決方案:重新設計秒殺商品頁面,不使用網站原來的商品詳細頁面,頁面內容靜態化,使用者請求不需要經過應用服務。

突然增加的網路及伺服器頻寬

假設商品頁面大小200K(主要是商品圖片大小),那麼需要的網路和伺服器頻寬是2G(200K×10000),這些網路頻寬是因為秒殺活動新增的,超過網站平時使用的頻寬。

解決方案:因為秒殺新增的`網路頻寬,必須和運營商重新購買或者租借。為了減輕網站伺服器的壓力,需要將秒殺商品頁面快取在CDN,同樣需要和CDN服務商臨時租借新增的出口頻寬。

直接下單

秒殺的遊戲規則是到了秒殺才能開始對商品下單購買,在此時間點之前,只能瀏覽商品資訊,不能下單。而下單頁面也是一個普通的URL,如果得到這個URL,不用等到秒殺開始就可以下單了。

解決方案:為了避免使用者直接訪問下單頁面URL,需要將改URL動態化,即使秒殺系統的開發者也無法在秒殺開始前訪問下單頁面的URL。辦法是在下單頁面URL加入由伺服器端生成的隨機數作為引數,在秒殺開始的時候才能得到。

如何控制秒殺商品頁面購買按鈕的點亮

購買按鈕只有在秒殺開始的時候才能點亮,在此之前是灰色的。如果該頁面是動態生成的,當然可以在伺服器端構造響應頁面輸出,控制該按鈕是灰色還 是點亮,但是為了減輕伺服器端負載壓力,更好地利用CDN、反向代理等效能優化手段,該頁面被設計為靜態頁面,快取在CDN、反向代理伺服器上,甚至使用者瀏覽器上。秒殺開始時,使用者重新整理頁面,請求根本不會到達應用伺服器。

解決方案:使用JavaScript指令碼控制,在秒殺商品靜態頁面中加入一個JavaScript檔案引用,該JavaScript檔案中包含 秒殺開始標誌為否;當秒殺開始的時候生成一個新的JavaScript檔案(檔名保持不變,只是內容不一樣),更新秒殺開始標誌為是,加入下單頁面的URL及隨機數引數(這個隨機數只會產生一個,即所有人看到的URL都是同一個,伺服器端可以用redis這種分散式快取伺服器來儲存隨機數),並被使用者瀏覽器載入,控制秒殺商品頁面的展示。這個JavaScript檔案的載入可以加上隨機版本號(例如),這樣就不會被瀏覽器、CDN和反向代理伺服器快取。

這個JavaScript檔案非常小,即使每次瀏覽器重新整理都訪問JavaScript檔案伺服器也不會對伺服器叢集和網路頻寬造成太大壓力。

如何只允許第一個提交的訂單被髮送到訂單子系統

由於最終能夠成功秒殺到商品的使用者只有一個,因此需要在使用者提交訂單時,檢查是否已經有訂單提交。如果已經有訂單提交成功,則需要更新 JavaScript檔案,更新秒殺開始標誌為否,購買按鈕變灰。事實上,由於最終能夠成功提交訂單的使用者只有一個,為了減輕下單頁面伺服器的負載壓力, 可以控制進入下單頁面的入口,只有少數使用者能進入下單頁面,其他使用者直接進入秒殺結束頁面。

解決方案:假設下單伺服器叢集有10臺伺服器,每臺伺服器只接受最多10個下單請求。在還沒有人提交訂單成功之前,如果一臺伺服器已經有十單了,而有的一單都沒處理,可能出現的使用者體驗不佳的場景是使用者第一次點選購買按鈕進入已結束頁面,再重新整理一下頁面,有可能被一單都沒有處理的伺服器處理,進入了填寫訂單的頁面,可以考慮通過cookie的方式來應對,符合一致性原則。當然可以採用最少連線的負載均衡演算法,出現上述情況的概率大大降低。

如何進行下單前置檢查

下單伺服器檢查本機已處理的下單請求數目:

如果超過10條,直接返回已結束頁面給使用者;

如果未超過10條,則使用者可進入填寫訂單及確認頁面;

檢查全域性已提交訂單數目:

已超過秒殺商品總數,返回已結束頁面給使用者;

未超過秒殺商品總數,提交到子訂單系統;

秒殺一般是定時上架

該功能實現方式很多。不過目前比較好的方式是:提前設定好商品的上架時間,使用者可以在前臺看到該商品,但是無法點選“立即購買”的按鈕。但是需要考慮的是,有人可以繞過前端的限制,直接通過URL的方式發起購買,這就需要在前臺商品頁面,以及bug頁面到後端的資料庫,都要進行時鐘同步。越在後端控制,安全性越高。

定時秒殺的話,就要避免賣家在秒殺前對商品做編輯帶來的不可預期的影響。這種特殊的變更需要多方面評估。一般禁止編輯,如需變更,可以走資料訂正多的流程。

減庫存的操作

有兩種選擇,一種是拍下減庫存 另外一種是付款減庫存;目前採用的“拍下減庫存”的方式,拍下就是一瞬間的事,對使用者體驗會好些。

庫存會帶來“超賣”的問題:售出數量多於庫存數量

由於庫存併發更新的問題,導致在實際庫存已經不足的情況下,庫存依然在減,導致賣家的商品賣得件數超過秒殺的預期。方案:採用樂觀鎖

auction_auctions set

quantity = #inQuantity#

where auction_id = #itemId# and quantity = #dbQuantity#

秒殺器的應對

秒殺器一般下單個購買及其迅速,根據購買記錄可以甄別出一部分。可以通過校驗碼達到一定的方法,這就要求校驗碼足夠安全,不被破解,採用的方式有:秒殺專用驗證碼,電視公佈驗證碼,秒殺答題。

  3 秒殺架構原則

儘量將請求攔截在系統上游

傳統秒殺系統之所以掛,請求都壓倒了後端資料層,資料讀寫鎖衝突嚴重,併發高響應慢,幾乎所有請求都超時,流量雖大,下單成功的有效流量甚小【一趟火車其實只有2000張票,200w個人來買,基本沒有人能買成功,請求有效率為0】。

讀多寫少的常用多使用快取

這是一個典型的讀多寫少的應用場景【一趟火車其實只有2000張票,200w個人來買,最多2000個人下單成功,其他人都是查詢庫存,寫比例只有0.1%,讀比例佔99.9%】,非常適合使用快取。