秒殺活動的技術(shù)挑戰(zhàn)
假設(shè)某網(wǎng)站秒殺活動只推出一件商品,預(yù)計(jì)會吸引 1 萬人參加活動妖泄,也就是說最大并發(fā)請求數(shù)是 10000驹沿,秒殺系統(tǒng)需要面對的技術(shù)挑戰(zhàn)有如下幾點(diǎn)。
對現(xiàn)有網(wǎng)站業(yè)務(wù)造成沖擊
秒殺活動只是網(wǎng)站營銷的一個附加活動蹈胡,這個活動具有時間短甚负,并發(fā)訪問量大的特點(diǎn),如果和網(wǎng)站原有應(yīng)用部署在一起审残,必然會對現(xiàn)有業(yè)務(wù)造成沖擊梭域,稍有不慎可能導(dǎo)致整個網(wǎng)站癱瘓。高并發(fā)下的應(yīng)用搅轿、數(shù)據(jù)庫負(fù)載
用戶在秒殺開始前病涨,通過不停刷新瀏覽器頁面以保證不會錯過秒殺,這些請求如果按照一般的網(wǎng)站應(yīng)用架構(gòu)璧坟,訪問應(yīng)用服務(wù)器既穆、連接數(shù)據(jù)庫,會對應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器造成極大的負(fù)載壓力雀鹃。突然增加的網(wǎng)絡(luò)及服務(wù)器帶寬
假設(shè)商品頁面大小 200K(主要是商品圖片大谢霉ぁ),那么需要的網(wǎng)絡(luò)和服務(wù)器帶寬是 2G(200K x 10000 ) 黎茎,這些網(wǎng)絡(luò)帶寬是因?yàn)槊霘⒒顒有略龅哪衣^網(wǎng)站平時使用的帶寬。直接下單
秒殺的游戲規(guī)則是到了秒殺時間才能開始對商品下單購買傅瞻,在此時間點(diǎn)之前踢代,只能瀏覽商品信息,不能下單嗅骄。而下單頁面也是一個普通的 URL胳挎,如果得到這個 URL,不用等到秒殺開始就可以下單了溺森。
秒殺系統(tǒng)的應(yīng)對策略
秒殺系統(tǒng)獨(dú)立部署
為了避免因?yàn)槊霘⒒顒拥母卟l(fā)訪問而拖垮整個網(wǎng)站慕爬,使整個網(wǎng)站不必面對蜂擁而來的用戶訪問窑眯,可將秒殺系統(tǒng)獨(dú)立部署;如果需要医窿,還可以使用獨(dú)立的域名伸但,使其與網(wǎng)站完全隔離,即使秒殺系統(tǒng)崩潰了留搔,也不會對網(wǎng)站造成任何影響更胖。秒殺商品頁面靜態(tài)化
重新設(shè)計(jì)秒殺商品頁面,不使用網(wǎng)站原來的商品詳情頁面隔显,頁面內(nèi)容靜態(tài)化:將商品描述却妨、商品參數(shù)、成交記錄和用戶評價全部寫入一個靜態(tài)頁面括眠,用戶請求不需要經(jīng)過應(yīng)用服務(wù)器的業(yè)務(wù)邏輯處理彪标,也不需要訪問數(shù)據(jù)庫。所以秒殺商品服務(wù)不需要部署動態(tài)的 Web 服務(wù)器和數(shù)據(jù)庫服務(wù)器掷豺。租借秒殺活動網(wǎng)絡(luò)帶
因?yàn)槊霘⑿略龅木W(wǎng)絡(luò)帶寬捞烟,必須和運(yùn)營商重新購買或者租借。為了減輕網(wǎng)站服務(wù)器的壓力当船,需要將秒殺商品頁面緩存在 CDN题画,同樣需要和 CDN 服務(wù)商臨時租借新增的出口帶寬。動態(tài)生成隨機(jī)下單頁面 URL
為了避免用戶直接訪問下單頁面 URL德频,需要將該 URL 動態(tài)化苍息,即使秒殺系統(tǒng)的開發(fā)者也無法在秒殺開始前訪問下單頁面的 URL。辦法是在下單頁面 URL 加入由服務(wù)器端生成的隨機(jī)數(shù)作為參數(shù)壹置,在秒殺開始的時候才能得到竞思。
秒殺系統(tǒng)架構(gòu)設(shè)計(jì)
秒殺系統(tǒng)為秒殺而設(shè)計(jì),不同于一般的網(wǎng)購行為钞护,參與秒殺活動的用戶更關(guān)心地是如何能快速刷新商品頁面盖喷,在秒殺開始的時候搶先進(jìn)入下單頁面,而不是商品詳情等用戶體驗(yàn)細(xì)節(jié)难咕,因此秒殺系統(tǒng)的頁面設(shè)計(jì)應(yīng)盡可能簡單课梳。
商品頁面中的購買按鈕只有在秒殺活動開始的時候才變亮,在此之前及秒殺商品賣出后步藕,該按鈕都是灰色的惦界,不可以點(diǎn)擊挑格。
下單表單也盡可能簡單咙冗,購買數(shù)量只能是一個且不可以修改,送貨地址和付款方式都使用用戶默認(rèn)設(shè)置漂彤,沒有默認(rèn)也可以不填雾消,允許等訂單提交后修改灾搏;只有第一個提交的訂單發(fā)送給網(wǎng)站的訂單子系統(tǒng), 其余用戶提交訂單后只能看到秒殺結(jié)束頁面立润。
除了上面提到的秒殺系統(tǒng)的技術(shù)挑戰(zhàn)及應(yīng)對策略缺前,還有一些其他問題需要處理蚂子。
如何控制秒殺商品頁面購買按鈕的點(diǎn)亮
購買按鈕只有在秒殺活動開始的時候才能點(diǎn)亮,在此之前是灰色的。如果該頁面是動態(tài)生成的帚桩,當(dāng)然可以在服務(wù)器端構(gòu)造響應(yīng)頁面輸出,控制該按鈕是灰色還是點(diǎn)亮砂蔽,但是為了減輕服務(wù)器端負(fù)載壓力尔苦,更好地利用 CDN 、反向代理等性能優(yōu)化手段提陶,該頁面被設(shè)計(jì)為靜態(tài)頁面烫沙,緩存在 CDN、反向代理服務(wù)器上隙笆,甚至用戶瀏覽器上锌蓄。秒殺開始時,用戶刷新頁面撑柔,請求根本不會到達(dá)應(yīng)用服務(wù)器瘸爽。
解決辦法是使用 JavaScript 腳本控制,在秒殺商品靜態(tài)頁面中加入一個 JavaScript 文件引用铅忿,該 JavaScript 文件中加入秒殺是否開始的標(biāo)志和下單頁面 URL 的隨機(jī)數(shù)參數(shù)蝶糯,當(dāng)秒殺幵始的時候生成一個新的 JavaScript 文件并被用戶瀏覽器加載, 控制秒殺商品頁面的展示辆沦。這 個 JavaScript 文件使用隨機(jī)版本號昼捍,并且不被瀏覽器、 CDN 和反向代理服務(wù)器緩存肢扯。
這個 JavaScript 文件非常小妒茬,即使每次瀏覽器刷新都訪問 JavaScript 文件服務(wù)器也不會對服務(wù)器集群和網(wǎng)絡(luò)帶寬造成太大壓力。
如何只允許第一個提交的訂單被發(fā)送到訂單子系統(tǒng)
由于最終能夠成功秒殺到商品的用戶只有一個蔚晨,因此需要在用戶提交訂單時乍钻,檢查是否已經(jīng)有訂單提交。事實(shí)上铭腕,由于最終能夠成功提交訂單的用戶只有一個银择,為了減輕下單頁面服務(wù)器的負(fù)載壓力,可以控制進(jìn)入下單頁面的入口累舷,只有少數(shù)用戶能進(jìn)入下單頁面浩考,其他用戶直接進(jìn)入秒殺結(jié)束頁面。假設(shè)下單服務(wù)器集群有 10 臺服務(wù)器被盈,每臺服務(wù)器只接受最多 10 個下單請求析孽。
秒殺系統(tǒng)的整體架構(gòu)圖
總結(jié)
秒殺是對網(wǎng)站架構(gòu)的極大考驗(yàn)搭伤,在難以預(yù)計(jì)和控制的高并發(fā)訪問的沖擊下,稍有不慎袜瞬,系統(tǒng)就會被用戶秒殺怜俐,導(dǎo)致整個系統(tǒng)宕機(jī),活動失敗邓尤,構(gòu)成重大事故拍鲤。因此在遵循秒殺活動游戲規(guī)則的基礎(chǔ)上,為了保證系統(tǒng)的安全汞扎,保持適度的公平公正即可殿漠。即使系統(tǒng)出了故障,也不應(yīng)該給用戶顯示出錯頁面佩捞,而是顯示秒殺活動結(jié)束頁面绞幌,避免不必要的困擾。另外維基百科的高性能架構(gòu)設(shè)計(jì)分析中提到的許多性能優(yōu)化設(shè)計(jì)都可以用于秒殺系統(tǒng)的優(yōu)化一忱。