
-? ? ?目錄? ? -
前面已經(jīng)寫了很多億級流量的文章, 中間講了各種處理思路, 這兒將這些思路與業(yè)務(wù)綜合起來, 情形一就是秒殺, 提到秒殺, 很多人都會覺得這是一件技術(shù)要求很高的事情, 因為這涉及到超大訪問量(可能瞬間千萬倍的用戶訪問商品)、維護數(shù)據(jù)一致性(不能超賣), 前者對性能有極高的要求, 而后者又正好拉低了性能,本文談?wù)劽霘⒌脑O(shè)計思路, 并在最后給出秒殺設(shè)計的簡單模型圖。

-? ? 秒殺的情景? ? -
生活中有很多秒殺的情景, 例如商家促銷, 像一元搶茅臺, 五毛錢搶寶馬(這兒只是一個例子), 假如一百萬人來搶十瓶茅臺, 這時候肯定不能多賣出, 也就是不能被大于10的人數(shù)搶到, 通常最后時間會有一個倒計時按鈕, 30...29...28......3...2...1 GO! 之后躍躍欲試的人們開始搶。
這時候有以下問題需要被考慮 :
第一是多個客戶端的時間如何保持同步, 也就是讓大家看到時間是一致的, 不能你顯示3, 而我這還顯示 30 。
第二是如何保證有沒有黃牛用機器人搶 。
第三是如何確保后端服務(wù)器可以支撐住這巨大的流量。

-? ? ?秒殺解決思路? ? -
有了上面的情景以及引出來的問題, 來看看秒殺方案的設(shè)計思路, 我們服務(wù)器如何應(yīng)對這一百萬的TPS呢?首先想到的是擴容, 詳情可以參考服務(wù)器擴容思路及問題分析?, 但這是不現(xiàn)實的, 因為擴容需要很多很多機器, TPS增加一萬倍對物理服務(wù)器的性能要求遠遠不止一萬倍, 另外對于一個商家來說, 為了這一次促銷活動購置服務(wù)器是不劃算的, 平時勢必有眾多的機器處于閑置狀態(tài)。沒法擴容, 那么也就意味著要使用其他方法, 如果所有請求訪問一臺物理機器肯定不行, 一百萬的數(shù)據(jù)訪問無論如何分庫分表都無濟于事, 因為面對的每一條都是熱點數(shù)據(jù), 所以要用到分布式架構(gòu)的思路。秒殺的技術(shù)方案
分布式, 可以降低服務(wù)器的壓力, 下面開始講述秒殺的設(shè)計思路。方案一
很明顯, 要讓一百萬用戶能夠同時打開搶貨的網(wǎng)頁, 勢必要用要到CDN(內(nèi)容分發(fā)網(wǎng)絡(luò), 對這個概念不清楚的話可以參考:全局負(fù)載均衡與CDN內(nèi)容分發(fā)), CDN主要作用有兩個, 一方面是將一些不會改變的靜態(tài)資源放到離客戶端較近的邊緣服務(wù)器上, 這樣客戶端請求數(shù)據(jù)的時候可以直接從邊緣服務(wù)器獲取, 降低中心服務(wù)器的壓力, 另外一方面可以把小服務(wù)部署到 CDN 結(jié)點上去,這樣,當(dāng)前端頁面來問開沒開始時,這個小服務(wù)除了告訴前端開沒開始外,它還可以統(tǒng)計下有多少人在線。每個小服務(wù)會把當(dāng)前在線等待秒殺的人數(shù)每隔一段時間就回傳給我們的數(shù)據(jù)中心,于是我們就知道全網(wǎng)總共在線的人數(shù)有多少。假設(shè),我們知道有大約 100 萬的人在線等著搶,那么,在我們快要開始的時候,由數(shù)據(jù)中心向各個部署在 CDN 結(jié)點上的小服務(wù)上傳遞一個概率值,這個概率值為CDN節(jié)點人數(shù)權(quán)重乘以獲獎概率, 比如說是??e。于是,當(dāng)秒殺開始的時候,這 100 萬用戶都在點下單按鈕,首先他們請求到的是 CDN 上的這些服務(wù),這些小服務(wù)按照???e?的量把用戶放到后面的數(shù)據(jù)中心,也就是放過去?人數(shù)???人數(shù)?e,剩下的都直接返回秒殺已結(jié)束。
-? ? 方案二? ? -
利用我們分布式中限流、網(wǎng)關(guān)等知識, 將請求層層篩選, 降低最后連接到數(shù)據(jù)庫的請求。首先也是利用CDN將靜態(tài)資源分發(fā)在邊緣服務(wù)器上, 當(dāng)進行服務(wù)請求時, 先進行鑒權(quán), 鑒權(quán)主要是篩選機器人等非人工搶購, 根據(jù)實際經(jīng)驗, 鑒權(quán)可以篩選很大一部分用戶, 例如是否登錄。當(dāng)鑒權(quán)確定是真實有效的用戶之后, 通過負(fù)載均衡(詳情可以參考LVS負(fù)載均衡理論以及算法概要)也就是LVS+Keepalived 將請求分配到不同的Nginx上,一般會建立Nginx集群, 然后再通過網(wǎng)關(guān)集群, 即使這樣還是要增加一些限流措施, 如果到這一步還是有很多請求壓到數(shù)據(jù)庫勢必?fù)尾蛔? 那么可以采取服務(wù)限流、服務(wù)降級等措施,進行削峰處理。到這兒理論上流量就不高了, 如果還是很高, 后面就將熱點數(shù)據(jù)放進緩存集群中進行預(yù)熱, 同時設(shè)置定時任務(wù),一方面關(guān)注數(shù)據(jù)庫與緩存的一致性, 另一方面關(guān)閉超時未支付的訂單, 當(dāng)訂單提交之后 交給任務(wù)隊列, 生成訂單、修改數(shù)據(jù)庫、做好持久化工作。這就是整個“秒殺”的技術(shù)細(xì)節(jié),是不是有點不敢相信?與這種秒殺業(yè)務(wù)類似的還有12306搶票, 這個也是瞬間高流量, 但是上面提到的架構(gòu)就不適合了,因為12306完全不知道用戶來是要買哪張火車票的。不知道這個信息,很不好過濾用戶,而且用戶在買票前需要有很多查詢操作,然后在查詢中選擇自己的車票。也就意味著沒法在開始就過濾用戶。12306 最好的應(yīng)對方式,除了不要一次把所有的票放出來,而是分批在不同的時間段把票放出來,這樣可以讓人們不要集中在一個時間點來搶票,做到人肉分流,可以降低一些并發(fā)度。另外,12306 最好是用預(yù)售的方式,讓大家把自己的購票先輸入到系統(tǒng)中。系統(tǒng)并不真正放票,而是把大家的需求都收集好,然后做整體統(tǒng)籌安排,該增加車次的增加車次,該加車廂的加車廂,這樣可以確保大家都能走。實在不行,就抽簽了。
-? ? 總結(jié)? ? -
我們可以看到,解決秒殺這種特定業(yè)務(wù)場景,可以使用 CDN 的邊緣結(jié)點來扛流量,然后過濾用戶請求(限流用戶請求),來保護數(shù)據(jù)中心的系統(tǒng),這樣才讓整個秒殺得以順利進行。也可以像方案二那樣逐層過濾請求, 這種業(yè)務(wù)場景和雙十一相同嗎? 如果像雙 11 那樣,想盡可能多地賣出商品,那么就不像秒殺了。這是要盡可能多地收訂單,但又不能超過庫存,其中還有大量的銀行支付,各大倉庫的庫存查詢和分配,這些都是非常慢的操作。為了保證一致性,還要能夠扛得住像雙 11 這樣的大規(guī)模并發(fā)訪問,那么,應(yīng)該怎么做呢?使用秒殺這樣的解決方案基本上不太科學(xué)了。這個時候就需要認(rèn)認(rèn)真真地做高并發(fā)的架構(gòu)和測試了,需要各個系統(tǒng)把自己的性能調(diào)整上去,還要小心地做性能規(guī)劃,更要把分布式的彈力設(shè)計做好,最后是要不停地做性能測試,找到整個架構(gòu)的系統(tǒng)瓶頸,然后不斷地做水平擴展,以解決大規(guī)模的并發(fā)。有些時候,我們總是在想數(shù)據(jù)中心的解決方案。其實,我們有時候也需要換一換思路,也許,在數(shù)據(jù)中心解決并不一定是最好的方式,放在邊緣來解決可能會更好一些。尤其是針對一些有地域特征的業(yè)務(wù),比如像外賣、共享單車、打車這樣的業(yè)務(wù)。其實,把一些簡單的業(yè)務(wù)邏輯放在邊緣,比放在數(shù)據(jù)中心不但能夠有更好的性能,還有更便宜的成本。我覺得,隨著請求量越來越大,數(shù)據(jù)也越來越多,數(shù)據(jù)中心是有點到瓶頸了,而需要邊緣結(jié)點來幫忙了。而且,這個邊緣化解決方案的趨勢也會越來越有優(yōu)勢。作者:等不到的口琴
來源:
www.cnblogs.com/Courage129/p/14493931.html
