秒殺帶來的挑戰(zhàn)

秒殺高并發(fā)

大規(guī)模并發(fā)帶來的挑戰(zhàn):

1? 一死、請求接口的合理設(shè)計:一個秒殺或者搶購頁面,通常分為2個部分,一個是靜態(tài)的HTML等內(nèi)容宫莱,另一個就是參與秒殺的Web后臺請求接口。 通常靜態(tài)HTML等內(nèi)容渡嚣,是通過CDN的部署梢睛,一般壓力不大,核心瓶頸實際上在后臺請求接口上识椰。這個后端接口绝葡,必須能夠支持高并發(fā)請求,同時腹鹉,非常 重要的一點藏畅,必須盡可能“快”,在最短的時間里返回用戶的請求結(jié)果功咒。為了實現(xiàn)盡可能快這一點愉阎,接口的后端存儲使用內(nèi)存級別的操作會更好一點。仍然直接面向 MySQL之類的存儲是不合適的力奋,如果有這種復(fù)雜業(yè)務(wù)的需求榜旦,都建議采用異步寫入。

當(dāng)然景殷,也有一些秒殺和搶購采用“滯后反饋”溅呢,就是說秒殺當(dāng)下不知道結(jié)果澡屡,一段時間后才可以從頁面中看到用戶是否秒殺成功。但是咐旧,這種屬于“偷懶”行為驶鹉,同時給用戶的體驗也不好,容易被用戶認(rèn)為是“暗箱操作”铣墨。

2室埋、? 高并發(fā)的挑戰(zhàn):一定要“快”我們通常衡量一個Web系統(tǒng)的吞吐率的指標(biāo)是QPS(Query Per Second,每秒處理請求數(shù))伊约,解決每秒數(shù)萬次的高并發(fā)場景姚淆,這個指標(biāo)非常關(guān)鍵。舉個例子碱妆,我們假設(shè)處理一個業(yè)務(wù)請求平均響應(yīng)時間為100ms肉盹,同時, 系統(tǒng)內(nèi)有20臺Apache的Web服務(wù)器疹尾,配置MaxClients為500個(表示Apache的最大連接數(shù)目)上忍。

那么,我們的Web系統(tǒng)的理論峰值QPS為(理想化的計算方式):

20*500/0.1 = 100000 (10萬QPS)

咦纳本?我們的系統(tǒng)似乎很強大窍蓝,1秒鐘可以處理完10萬的請求,5w/s的秒殺似乎是“紙老虎”哈繁成。實際情況吓笙,當(dāng)然沒有這么理想。在高并發(fā)的實際場景下巾腕,機器都處于高負(fù)載的狀態(tài)面睛,在這個時候平均響應(yīng)時間會被大大增加。

就Web服務(wù)器而言尊搬,Apache打開了越多的連接進(jìn)程叁鉴,CPU需要處理的上下文切換也越多,額外增加了CPU的消耗佛寿,然后就直接導(dǎo)致平均響應(yīng)時間 增加幌墓。因此上述的MaxClient數(shù)目,要根據(jù)CPU冀泻、內(nèi)存等硬件因素綜合考慮常侣,絕對不是越多越好〉妫可以通過Apache自帶的abench來測試一 下胳施,取一個合適的值。然后肢专,我們選擇內(nèi)存操作級別的存儲的Redis巾乳,在高并發(fā)的狀態(tài)下您没,存儲的響應(yīng)時間至關(guān)重要。網(wǎng)絡(luò)帶寬雖然也是一個因素胆绊,不過,這種 請求數(shù)據(jù)包一般比較小欧募,一般很少成為請求的瓶頸压状。負(fù)載均衡成為系統(tǒng)瓶頸的情況比較少,在這里不做討論哈跟继。

那么問題來了种冬,假設(shè)我們的系統(tǒng),在5w/s的高并發(fā)狀態(tài)下舔糖,平均響應(yīng)時間從100ms變?yōu)?50ms(實際情況娱两,甚至更多):

20*500/0.25 = 40000 (4萬QPS)

于是,我們的系統(tǒng)剩下了4w的QPS金吗,面對5w每秒的請求十兢,中間相差了1w。

然后摇庙,這才是真正的惡夢開始旱物。舉個例子,高速路口卫袒,1秒鐘來5部車宵呛,每秒通過5部車,高速路口運作正常夕凝。突然宝穗,這個路口1秒鐘只能通過4部車,車流量仍然依舊码秉,結(jié)果必定出現(xiàn)大塞車逮矛。(5條車道忽然變成4條車道的感覺)

同理,某一個秒內(nèi)泡徙,20*500個可用連接進(jìn)程都在滿負(fù)荷工作中橱鹏,卻仍然有1萬個新來請求,沒有連接進(jìn)程可用堪藐,系統(tǒng)陷入到異常狀態(tài)也是預(yù)期之內(nèi)莉兰。其實在正常的非高并發(fā)的業(yè)務(wù)場景中,也有類似的情況出現(xiàn)礁竞,某個業(yè)務(wù)請求接口出現(xiàn)問題糖荒,響應(yīng)時間極慢,將整個Web請求響應(yīng)時間拉得很長模捂,逐漸將Web服務(wù)器的可用連接數(shù)占滿捶朵,其他正常的業(yè)務(wù)請求蜘矢,無連接進(jìn)程可用。

更可怕的問題是综看,是用戶的行為特點品腹,系統(tǒng)越是不可用,用戶的點擊越頻繁红碑,惡性循環(huán)最終導(dǎo)致“雪崩”(其中一臺Web機器掛了舞吭,導(dǎo)致流量分散到其他正常工作的機器上,再導(dǎo)致正常的機器也掛析珊,然后惡性循環(huán))羡鸥,將整個Web系統(tǒng)拖垮。 多個人訪問同一個一個文件忠寻,處理高并發(fā):承載更多的并發(fā)惧浴,考慮內(nèi)存的問題,降低運行成本奕剃,從而并發(fā)量更大衷旅,一天訪問次數(shù)(訪問量)pv,用戶訪問(uv)祭饭,計算獨立Ip是正常用戶7-8倍芜茵,統(tǒng)計(網(wǎng)站統(tǒng)計,頁面統(tǒng)計)倡蝙,活躍度App100萬的訪問量九串,統(tǒng)計獨立Ip大約是5倍。防止并發(fā):消息隊列寺鸥,php push pop shift mysql 鎖表 行鎖 nosql redis memcacheq mongo ;大訪問量(靜態(tài)優(yōu)化);優(yōu)化從硬件開始猪钮,cpu 內(nèi)存,負(fù)載均衡:多臺服務(wù)器胆建,mysql 分表(加速查詢) 分區(qū)(水平分區(qū):將數(shù)據(jù)轉(zhuǎn)移到其他服務(wù)器烤低,業(yè)務(wù)沖突時,把一條數(shù)據(jù)分割成幾條數(shù)據(jù)實現(xiàn))

3笆载、 重啟與過載保護(hù):如果系統(tǒng)發(fā)生“雪崩”扑馁,貿(mào)然重啟服務(wù),是無法解決問題的凉驻。最常見的現(xiàn)象是腻要,啟動起來后,立刻掛掉涝登。這個時候雄家,最好在入口層將流量拒絕,然后再將重啟胀滚。如果是redis/memcache這種服務(wù)也掛了趟济,重啟的時候需要注意“預(yù)熱”乱投,并且很可能需要比較長的時間。

秒殺和搶購的場景顷编,流量往往是超乎我們系統(tǒng)的準(zhǔn)備和想象的戚炫。這個時候,過載保護(hù)是必要的媳纬。如果檢測到系統(tǒng)滿負(fù)載狀態(tài)嘹悼,拒絕請求也是一種保護(hù)措施。在 前端設(shè)置過濾是最簡單的方式层宫,但是,這種做法是被用戶“千夫所指”的行為其监。更合適一點的是萌腿,將過載保護(hù)設(shè)置在CGI入口層,快速將客戶的直接請求返回抖苦。

注:秒殺和搶購收到了“海量”的請求毁菱,實際上里面的水分是很大的。不少用戶锌历,為了“搶“到商品贮庞,會使用“刷票工具”等類型的輔助工具,幫助他們發(fā)送盡可 能多的請求到服務(wù)器究西。還有一部分高級用戶窗慎,制作強大的自動請求腳本。這種做法的理由也很簡單卤材,就是在參與秒殺和搶購的請求中遮斥,自己的請求數(shù)目占比越多,成功的概率越高扇丛。

**作弊的手段:進(jìn)攻與防守**:

A:? 同一個賬號术吗,一次性發(fā)出多個請求

Question?? 部分用戶通過瀏覽器的插件或者其他工具,在秒殺開始的時間里帆精,以自己的賬號较屿,一次發(fā)送上百甚至更多的請求。實際上卓练,這樣的用戶破壞了秒殺和搶購的公平性隘蝎。

這種請求在某些沒有做數(shù)據(jù)安全處理的系統(tǒng)里,也可能造成另外一種破壞昆庇,導(dǎo)致某些判斷條件被繞過末贾。例如一個簡單的領(lǐng)取邏輯,先判斷用戶是否有參與記 錄整吆,如果沒有則領(lǐng)取成功拱撵,最后寫入到參與記錄中辉川。這是個非常簡單的邏輯,但是拴测,在高并發(fā)的場景下乓旗,存在深深的漏洞。多個并發(fā)請求通過負(fù)載均衡服務(wù)器集索,分配 到內(nèi)網(wǎng)的多臺Web服務(wù)器屿愚,它們首先向存儲發(fā)送查詢請求,然后务荆,在某個請求成功寫入?yún)⑴c記錄的時間差內(nèi)妆距,其他的請求獲查詢到的結(jié)果都是“沒有參與記錄”。 這里函匕,就存在邏輯判斷被繞過的風(fēng)險娱据。

Settled(解決):? 在程序入口處,一個賬號只允許接受1個請求盅惜,其他請求過濾中剩。不僅解決了同一個賬號,發(fā)送N個請求的問題抒寂,還保證了后續(xù)的邏輯流程的安全结啼。實現(xiàn)方案, 可以通過Redis這種內(nèi)存緩存服務(wù)屈芜,寫入一個標(biāo)志位(只允許1個請求寫成功郊愧,結(jié)合watch的樂觀鎖的特性),成功寫入的則可以繼續(xù)參加沸伏「馍海或者,自己實現(xiàn)一個服務(wù)毅糟,將同一個賬號的請求放入一個隊列中红选,處理完一個,再處理下一個姆另。

B: 多個賬號喇肋,一次性發(fā)送多個請求

Question?? 很多公司的賬號注冊功能,在發(fā)展早期幾乎是沒有限制的迹辐,很容易就可以注冊很多個賬號蝶防。因此,也導(dǎo)致了出現(xiàn)了一些特殊的工作室明吩,通過編寫自動注冊腳 本间学,積累了一大批“僵尸賬號”,數(shù)量龐大,幾萬甚至幾十萬的賬號不等低葫,專門做各種刷的行為(這就是微博中的“僵尸粉“的來源)详羡。舉個例子,例如微博中有轉(zhuǎn) 發(fā)抽獎的活動嘿悬,如果我們使用幾萬個“僵尸號”去混進(jìn)去轉(zhuǎn)發(fā)实柠,這樣就可以大大提升我們中獎的概率。

這種賬號善涨,使用在秒殺和搶購里窒盐,也是同一個道理。例如钢拧,iPhone官網(wǎng)的搶購蟹漓,火車票黃牛黨。

Settled(解決):? 這種場景源内,可以通過檢測指定機器IP請求頻率就可以解決牧牢,如果發(fā)現(xiàn)某個IP請求頻率很高,可以給它彈出一個驗證碼或者直接禁止它的請求:

彈出驗證碼姿锭,最核心的追求,就是分辨出真實用戶伯铣。因此呻此,大家可能經(jīng)常發(fā)現(xiàn),網(wǎng)站彈出的驗證碼腔寡,有些是“鬼神亂舞”的樣子焚鲜, 有時讓我們根本無法看清。他們這樣做的原因放前,其實也是為了讓驗證碼的圖片不被輕易識別忿磅,因為強大的“自動腳本”可以通過圖片識別里面的字符,然后讓腳本自 動填寫驗證碼凭语。實際上葱她,有一些非常創(chuàng)新的驗證碼,效果會比較好似扔,例如給你一個簡單問題讓你回答吨些,或者讓你完成某些簡單操作(例如百度貼吧的驗證碼)。

直接禁止IP炒辉,實際上是有些粗暴的豪墅,因為有些真實用戶的網(wǎng)絡(luò)場景恰好是同一出口IP的,可能會有“誤傷“黔寇。但是這一個做法簡單高效偶器,根據(jù)實際場景使用可以獲得很好的效果。

**高并發(fā)下的數(shù)據(jù)安全如何保證?**

A? 超發(fā)的原因:自由主題假設(shè)某個搶購場景中屏轰,我們一共只有100個商品颊郎,在最后一刻,我們已經(jīng)消耗了99個商品亭枷,僅剩最后一個袭艺。這個時候,系統(tǒng)發(fā)來多個并發(fā)請求叨粘,這批請求讀取到的商品余量都是99個猾编,然后都通過了這一個余量判斷,最終導(dǎo)致超發(fā)升敲。(同文章前面說的場景)答倡。

B 悲觀鎖思路:解決線程安全的思路很多,可以從“悲觀鎖”的方向開始討論驴党。 悲觀鎖瘪撇,也就是在修改數(shù)據(jù)的時候,采用鎖定狀態(tài)港庄,排斥外部請求的修改倔既。遇到加鎖的狀態(tài),就必須等待鹏氧。

雖然上述的方案的確解決了線程安全的問題渤涌,但是,別忘記把还,我們的場景是“高并發(fā)”实蓬。也就是說,會很多這樣的修改請求吊履,每個請求都需要等待 “鎖”安皱,某些線程可能永遠(yuǎn)都沒有機會搶到這個“鎖”,這種請求就會死在那里艇炎。同時酌伊,這種請求會很多,瞬間增大系統(tǒng)的平均響應(yīng)時間缀踪,結(jié)果是可用連接數(shù)被耗 盡腺晾,系統(tǒng)陷入異常。

C? FIFO隊列思路:我們直接將請求放入隊列中的辜贵,采用FIFO(First Input First Output悯蝉,先進(jìn)先出),這樣的話托慨,我們就不會導(dǎo)致某些請求永遠(yuǎn)獲取不到鎖鼻由。看到這里,是不是有點強行將多線程變成單線程的感覺然后蕉世,我們現(xiàn)在解決了鎖的問題蔼紧,全部請求采用“先進(jìn)先出”的隊列方式來處理。那么新的問題來了狠轻,高并發(fā)的場景下奸例,因為請求很多,很可能一瞬 間將隊列內(nèi)存“撐爆”向楼,然后系統(tǒng)又陷入到了異常狀態(tài)查吊。或者設(shè)計一個極大的內(nèi)存隊列湖蜕,也是一種方案逻卖,但是,系統(tǒng)處理完一個隊列內(nèi)請求的速度根本無法和瘋狂涌 入隊列中的數(shù)目相比昭抒。也就是說评也,隊列內(nèi)的請求會越積累越多,最終Web系統(tǒng)平均響應(yīng)時候還是會大幅下降灭返,系統(tǒng)還是陷入異常盗迟。D 樂觀鎖思路:。樂觀鎖熙含,是相對于“悲觀鎖”采用更為寬松的加鎖機制诈乒,大都是采用帶版本號 (Version)更新。實現(xiàn)就是婆芦,這個數(shù)據(jù)所有請求都有資格去修改,但會獲得一個該數(shù)據(jù)的版本號喂饥,只有版本號符合的才能更新成功消约,其他的返回?fù)屬徥 ?這樣的話,我們就不需要考慮隊列的問題员帮,不過或粮,它會增大CPU的計算開銷。但是捞高,綜合來說氯材,這是一個比較好的解決方案。

Web系統(tǒng)大規(guī)模并發(fā)——電商秒殺與搶購 – 徐漢彬Hansion – 技術(shù)行者

有很多軟件和服務(wù)都“樂觀鎖”功能的支持硝岗,例如Redis中的watch就是其中之一氢哮。通過這個實現(xiàn),我們保證了數(shù)據(jù)的安全型檀。

互聯(lián)網(wǎng)正在高速發(fā)展冗尤,使用互聯(lián)網(wǎng)服務(wù)的用戶越多,高并發(fā)的場景也變得越來越多。電商秒殺和搶購裂七,是兩個比較典型的互聯(lián)網(wǎng)高并發(fā)場景皆看。雖然我們解決問題的具體技術(shù)方案可能千差萬別,但是遇到的挑戰(zhàn)卻是相似的背零,因此解決問題的思路也異曲同工腰吟。

--------------------------------------------------------------------------------

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市徙瓶,隨后出現(xiàn)的幾起案子毛雇,更是在濱河造成了極大的恐慌,老刑警劉巖倍啥,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禾乘,死亡現(xiàn)場離奇詭異,居然都是意外死亡虽缕,警方通過查閱死者的電腦和手機始藕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氮趋,“玉大人伍派,你說我怎么就攤上這事∈P玻” “怎么了诉植?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昵观。 經(jīng)常有香客問我晾腔,道長,這世上最難降的妖魔是什么啊犬? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任灼擂,我火速辦了婚禮,結(jié)果婚禮上觉至,老公的妹妹穿的比我還像新娘剔应。我一直安慰自己,他們只是感情好语御,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布峻贮。 她就那樣靜靜地躺著,像睡著了一般应闯。 火紅的嫁衣襯著肌膚如雪纤控。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天碉纺,我揣著相機與錄音嚼黔,去河邊找鬼细层。 笑死,一個胖子當(dāng)著我的面吹牛唬涧,可吹牛的內(nèi)容都是我干的疫赎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碎节,長吁一口氣:“原來是場噩夢啊……” “哼捧搞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狮荔,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胎撇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后殖氏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晚树,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年雅采,在試婚紗的時候發(fā)現(xiàn)自己被綠了爵憎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡婚瓜,死狀恐怖宝鼓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巴刻,我是刑警寧澤愚铡,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站胡陪,受9級特大地震影響沥寥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柠座,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一邑雅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愚隧,春花似錦、人聲如沸锻全。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳄厌。三九已至荞胡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間了嚎,已是汗流浹背泪漂。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工廊营, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萝勤。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓露筒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親敌卓。 傳聞我的和親對象是個殘疾皇子慎式,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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