秒殺系統(tǒng)的流量峰值

如果你看過秒殺系統(tǒng)的流量監(jiān)控圖的話溜腐,你會發(fā)現(xiàn)它是一條直線钱豁,就在秒殺開始那一秒是一條很直很直的線,這是因為秒殺請求在時間上高度集中于某一特定的時間點。這樣一來疯淫,就會導(dǎo)致一個特別高的流量峰值地来,它對資源的消耗是瞬時的。

但是對秒殺這個場景來說熙掺,最終能夠搶到商品的人數(shù)是固定的靠抑,也就是說 100 人和 10000 人發(fā)起請求的結(jié)果都是一樣的,并發(fā)度越高适掰,無效請求也越多。

但是從業(yè)務(wù)上來說荠列,秒殺活動是希望更多的人來參與的类浪,也就是開始之前希望有更多的人來刷頁面,但是真正開始下單時肌似,秒殺請求并不是越多越好费就。因此我們可以設(shè)計一些規(guī)則,讓并發(fā)的請求更多地延緩川队,而且我們甚至可以過濾掉一些無效請求力细。

為什么要削峰

為什么要削峰呢?或者說峰值會帶來哪些壞處固额?

我們知道服務(wù)器的處理資源是恒定的眠蚂,你用或者不用它的處理能力都是一樣的,所以出現(xiàn)峰值的話斗躏,很容易導(dǎo)致忙到處理不過來逝慧,閑的時候卻又沒有什么要處理。但是由于要保證服務(wù)質(zhì)量啄糙,我們的很多處理資源只能按照忙的時候來預(yù)估笛臣,而這會導(dǎo)致資源的一個浪費。

這就好比因為存在早高峰和晚高峰的問題隧饼,所以有了錯峰限行的解決方案沈堡。削峰的存在,一是可以讓服務(wù)端處理變得更加平穩(wěn)燕雁,二是可以節(jié)省服務(wù)器的資源成本诞丽。針對秒殺這一場景,削峰從本質(zhì)上來說就是更多地延緩用戶請求的發(fā)出拐格,以便減少和過濾掉一些無效請求率拒,它遵從“請求數(shù)要盡量少”的原則。

今天禁荒,我就來介紹一下流量削峰的一些操作思路:排隊猬膨、答題、分層過濾。這幾種方式都是無損(即不會損失用戶的發(fā)出請求)的實現(xiàn)方案勃痴,當(dāng)然還有些有損的實現(xiàn)方案谒所,包括我們后面要介紹的關(guān)于穩(wěn)定性的一些辦法,比如限流和機器負(fù)載保護等一些強制措施也能達(dá)到削峰保護的目的沛申,當(dāng)然這都是不得已的一些措施劣领,因此就不歸類到這里了。

排隊

要對流量進(jìn)行削峰铁材,最容易想到的解決方案就是用消息隊列來緩沖瞬時流量尖淘,把同步的直接調(diào)用轉(zhuǎn)換成異步的間接推送,中間通過一個隊列在一端承接瞬時的流量洪峰著觉,在另一端平滑地將消息推送出去村生。在這里,消息隊列就像“水庫”一樣饼丘, 攔蓄上游的洪水趁桃,削減進(jìn)入下游河道的洪峰流量,從而達(dá)到減免洪水災(zāi)害的目的肄鸽。

用消息隊列來緩沖瞬時流量的方案卫病,如下圖所示:

圖 1 用消息隊列來緩沖瞬時流量??

但是,如果流量峰值持續(xù)一段時間達(dá)到了消息隊列的處理上限典徘,例如本機的消息積壓達(dá)到了存儲空間的上限蟀苛,消息隊列同樣也會被壓垮,這樣雖然保護了下游的系統(tǒng)逮诲,但是和直接把請求丟棄也沒多大的區(qū)別屹逛。就像遇到洪水爆發(fā)時,即使是有水庫恐怕也無濟于事汛骂。

除了消息隊列罕模,類似的排隊方式還有很多,例如:

利用線程池加鎖等待也是一種常用的排隊方式帘瞭;

先進(jìn)先出淑掌、先進(jìn)后出等常用的內(nèi)存排隊算法的實現(xiàn)方式;

把請求序列化到文件中蝶念,然后再順序地讀文件(例如基于 MySQL binlog 的同步機制)來恢復(fù)請求等方式抛腕。

可以看到,這些方式都有一個共同特征媒殉,就是把“一步的操作”變成“兩步的操作”担敌,其中增加的一步操作用來起到緩沖的作用。

說到這里你可能會說廷蓉,這樣一來增加了訪問請求的路徑啊全封,并不符合我們介紹的“4 要 1 不要”原則。沒錯,的確看起來不太合理刹悴,但是如果不增加一個緩沖步驟行楞,那么在一些場景下系統(tǒng)很可能會直接崩潰,所以最終還是需要你做出妥協(xié)和平衡土匀。

答題

你是否還記得子房,最早期的秒殺只是純粹地刷新頁面和點擊購買按鈕,它是后來才增加了答題功能的就轧。那么证杭,為什么要增加答題功能呢?

這主要是為了增加購買的復(fù)雜度妒御,從而達(dá)到兩個目的解愤。

第一個目的是防止部分買家使用秒殺器在參加秒殺時作弊。2011 年秒殺非承。火的時候,秒殺器也比較猖獗兰怠,因而沒有達(dá)到全民參與和營銷的目的梦鉴,所以系統(tǒng)增加了答題來限制秒殺器。增加答題后揭保,下單的時間基本控制在 2s 后肥橙,秒殺器的下單比例也大大下降。答題頁面如下圖所示侣滩。

圖 2 答題頁面

第二個目的其實就是延緩請求逸贾,起到對請求流量進(jìn)行削峰的作用痴施,從而讓系統(tǒng)能夠更好地支持瞬時的流量高峰。這個重要的功能就是把峰值的下單請求拉長椭坚,從以前的 1s 之內(nèi)延長到 2s~10s。這樣一來搏色,請求峰值基于時間分片了善茎。這個時間的分片對服務(wù)端處理并發(fā)非常重要,會大大減輕壓力频轿。而且垂涯,由于請求具有先后順序,靠后的請求到來時自然也就沒有庫存了航邢,因此根本到不了最后的下單步驟耕赘,所以真正的并發(fā)寫就非常有限了。這種設(shè)計思路目前用得非常普遍膳殷,如當(dāng)年支付寶的“咻一咻”操骡、微信的“搖一搖”都是類似的方式。

這里,我重點說一下秒殺答題的設(shè)計思路当娱。

圖 3 秒殺答題

如上圖所示吃既,整個秒殺答題的邏輯主要分為 3 部分。

題庫生成模塊跨细,這個部分主要就是生成一個個問題和答案鹦倚,其實題目和答案本身并不需要很復(fù)雜,重要的是能夠防止由機器來算出結(jié)果冀惭,即防止秒殺器來答題震叙。

題庫的推送模塊,用于在秒殺答題前散休,把題目提前推送給詳情系統(tǒng)和交易系統(tǒng)媒楼。題庫的推送主要是為了保證每次用戶請求的題目是唯一的,目的也是防止答題作弊戚丸。

題目的圖片生成模塊划址,用于把題目生成為圖片格式,并且在圖片里增加一些干擾因素限府。這也同樣是為防止機器直接來答題夺颤,它要求只有人才能理解題目本身的含義。這里還要注意一點胁勺,由于答題時網(wǎng)絡(luò)比較擁擠世澜,我們應(yīng)該把題目的圖片提前推送到 CDN 上并且要進(jìn)行預(yù)熱,不然的話當(dāng)用戶真正請求題目時署穗,圖片可能加載比較慢寥裂,從而影響答題的體驗。

其實真正答題的邏輯比較簡單案疲,很好理解:當(dāng)用戶提交的答案和題目對應(yīng)的答案做比較封恰,如果通過了就繼續(xù)進(jìn)行下一步的下單邏輯,否則就失敗褐啡。我們可以把問題和答案用下面這樣的 key 來進(jìn)行 MD5 加密:

問題 key:userId+itemId+question_Id+time+PK

答案 key:userId+itemId+answer+PK

驗證的邏輯如下圖所示:

圖 4 答題的驗證邏輯

注意俭驮,這里面的驗證邏輯,除了驗證問題的答案以外春贸,還包括用戶本身身份的驗證混萝,例如是否已經(jīng)登錄、用戶的 Cookie 是否完整萍恕、用戶是否重復(fù)頻繁提交等逸嘀。

除了做正確性驗證,我們還可以對提交答案的時間做些限制允粤,例如從開始答題到接受答案要超過 1s崭倘,因為小于 1s 是人為操作的可能性很小翼岁,這樣也能防止機器答題的情況。

分層過濾

前面介紹的排隊和答題要么是少發(fā)請求司光,要么對發(fā)出來的請求進(jìn)行緩沖琅坡,而針對秒殺場景還有一種方法,就是對請求進(jìn)行分層過濾残家,從而過濾掉一些無效的請求榆俺。分層過濾其實就是采用“漏斗”式設(shè)計來處理請求的,如下圖所示坞淮。

圖 5 分層過濾

假如請求分別經(jīng)過 CDN茴晋、前臺讀系統(tǒng)(如商品詳情系統(tǒng))、后臺系統(tǒng)(如交易系統(tǒng))和數(shù)據(jù)庫這幾層回窘,那么:

大部分?jǐn)?shù)據(jù)和流量在用戶瀏覽器或者 CDN 上獲取诺擅,這一層可以攔截大部分?jǐn)?shù)據(jù)的讀取啡直;

經(jīng)過第二層(即前臺系統(tǒng))時數(shù)據(jù)(包括強一致性的數(shù)據(jù))盡量得走 Cache烁涌,過濾一些無效的請求;

再到第三層后臺系統(tǒng)酒觅,主要做數(shù)據(jù)的二次檢驗撮执,對系統(tǒng)做好保護和限流,這樣數(shù)據(jù)量和請求就進(jìn)一步減少阐滩;

最后在數(shù)據(jù)層完成數(shù)據(jù)的強一致性校驗二打。

這樣就像漏斗一樣县忌,盡量把數(shù)據(jù)量和請求量一層一層地過濾和減少了掂榔。

分層過濾的核心思想是:在不同的層次盡可能地過濾掉無效請求,讓“漏斗”最末端的才是有效請求症杏。而要達(dá)到這種效果装获,我們就必須對數(shù)據(jù)做分層的校驗。

分層校驗的基本原則是:

將動態(tài)請求的讀數(shù)據(jù)緩存(Cache)在 Web 端厉颤,過濾掉無效的數(shù)據(jù)讀穴豫;

對讀數(shù)據(jù)不做強一致性校驗,減少因為一致性校驗產(chǎn)生瓶頸的問題逼友;

對寫數(shù)據(jù)進(jìn)行基于時間的合理分片精肃,過濾掉過期的失效請求;

對寫請求做限流保護帜乞,將超出系統(tǒng)承載能力的請求過濾掉司抱;

對寫數(shù)據(jù)進(jìn)行強一致性校驗,只保留最后有效的數(shù)據(jù)黎烈。

分層校驗的目的是:在讀系統(tǒng)中习柠,盡量減少由于一致性校驗帶來的系統(tǒng)瓶頸匀谣,但是盡量將不影響性能的檢查條件提前,如用戶是否具有秒殺資格资溃、商品狀態(tài)是否正常武翎、用戶答題是否正確、秒殺是否已經(jīng)結(jié)束溶锭、是否非法請求宝恶、營銷等價物是否充足等;在寫數(shù)據(jù)系統(tǒng)中暖途,主要對寫的數(shù)據(jù)(如“庫存”)做一致性檢查卑惜,最后在數(shù)據(jù)庫層保證數(shù)據(jù)的最終準(zhǔn)確性(如“庫存”不能減為負(fù)數(shù))。

總結(jié)一下

今天驻售,我介紹了如何在網(wǎng)站面臨大流量沖擊時進(jìn)行請求的削峰露久,并主要介紹了削峰的 3 種處理方式:一個是通過隊列來緩沖請求,即控制請求的發(fā)出欺栗;一個是通過答題來延長請求發(fā)出的時間毫痕,在請求發(fā)出后承接請求時進(jìn)行控制,最后再對不符合條件的請求進(jìn)行過濾迟几;最后一種是對請求進(jìn)行分層過濾消请。

其中,隊列緩沖方式更加通用类腮,它適用于內(nèi)部上下游系統(tǒng)之間調(diào)用請求不平緩的場景臊泰,由于內(nèi)部系統(tǒng)的服務(wù)質(zhì)量要求不能隨意丟棄請求,所以使用消息隊列能起到很好的削峰和緩沖作用蚜枢。

而答題更適用于秒殺或者營銷活動等應(yīng)用場景缸逃,在請求發(fā)起端就控制發(fā)起請求的速度,因為越到后面無效請求也會越多厂抽,所以配合后面介紹的分層攔截的方式需频,可以更進(jìn)一步減少無效請求對系統(tǒng)資源的消耗。

分層過濾非常適合交易性的寫請求筷凤,比如減庫存或者拼車這種場景昭殉,在讀的時候需要知道還有沒有庫存或者是否還有剩余空座位。但是由于庫存和座位又是不停變化的藐守,所以讀的數(shù)據(jù)是否一定要非常準(zhǔn)確呢挪丢?其實不一定,你可以放一些請求過去卢厂,然后在真正減的時候再做強一致性保證乾蓬,這樣既過濾一些請求又解決了強一致性讀的瓶頸。

不過足淆,在削峰的處理方式上除了采用技術(shù)手段巢块,其實還可以采用業(yè)務(wù)手段來達(dá)到一定效果礁阁,例如在零點開啟大促的時候由于流量太大導(dǎo)致支付系統(tǒng)阻塞,這個時候可以采用發(fā)放優(yōu)惠券族奢、發(fā)起抽獎活動等方式姥闭,將一部分流量分散到其他地方,這樣也能起到緩沖流量的作用越走。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末棚品,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子廊敌,更是在濱河造成了極大的恐慌铜跑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骡澈,死亡現(xiàn)場離奇詭異锅纺,居然都是意外死亡,警方通過查閱死者的電腦和手機肋殴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門囤锉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人护锤,你說我怎么就攤上這事官地。” “怎么了烙懦?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵驱入,是天一觀的道長。 經(jīng)常有香客問我氯析,道長亏较,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任魄鸦,我火速辦了婚禮宴杀,結(jié)果婚禮上癣朗,老公的妹妹穿的比我還像新娘拾因。我一直安慰自己,他們只是感情好旷余,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布绢记。 她就那樣靜靜地躺著,像睡著了一般正卧。 火紅的嫁衣襯著肌膚如雪蠢熄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天炉旷,我揣著相機與錄音签孔,去河邊找鬼叉讥。 笑死,一個胖子當(dāng)著我的面吹牛饥追,可吹牛的內(nèi)容都是我干的图仓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼但绕,長吁一口氣:“原來是場噩夢啊……” “哼救崔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捏顺,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤六孵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后幅骄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劫窒,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年拆座,在試婚紗的時候發(fā)現(xiàn)自己被綠了烛亦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡懂拾,死狀恐怖煤禽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岖赋,我是刑警寧澤檬果,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站唐断,受9級特大地震影響选脊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脸甘,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一恳啥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丹诀,春花似錦钝的、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至枚荣,卻和暖如春碗脊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背橄妆。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工衙伶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祈坠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓矢劲,卻偏偏與公主長得像颁虐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子卧须,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容