自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高并發(fā)秒殺系統(tǒng)總結(jié)

開發(fā) 前端
大家也許開發(fā)過(guò)高并發(fā)的系統(tǒng)或者秒殺程序,但肯定都有接觸過(guò),像電商平臺(tái)的秒殺、搶購(gòu)等活動(dòng),還有12306春運(yùn)搶票。 活動(dòng)周期短,瞬間流量大(高并發(fā)),技術(shù)在這種情況下,會(huì)發(fā)生和要做的事。

大家也許開發(fā)過(guò)高并發(fā)的系統(tǒng)或者秒殺程序,但肯定都有接觸過(guò),像電商平臺(tái)的秒殺、搶購(gòu)等活動(dòng),還有12306春運(yùn)搶票。

活動(dòng)周期短,瞬間流量大(高并發(fā)),技術(shù)在這種情況下,會(huì)發(fā)生和要做的事。

[[243754]]

第一:高并發(fā)

技術(shù)要做的事,一方面優(yōu)化程序,讓程序性能最優(yōu),單次請(qǐng)求時(shí)間能從50ms優(yōu)化到25ms,那就可以在一秒鐘內(nèi)成功響應(yīng)翻倍的請(qǐng)求了。

另一方面就是增加服務(wù)器,用更大的集群來(lái)處理用戶請(qǐng)求,設(shè)計(jì)好一個(gè)可靠且靈活擴(kuò)充的分布式方案就更加重要了。

第二:時(shí)間短

火熱的秒殺活動(dòng),真的是一秒鐘以內(nèi)就會(huì)把商品搶購(gòu)一空,而大部分用戶的感受是,提交訂單的過(guò)程卻要等待好幾秒、甚至十幾秒,更糟糕的當(dāng)然是請(qǐng)求報(bào)錯(cuò)。

那么一個(gè)好的秒殺體驗(yàn),當(dāng)然希望盡可能減少用戶等待時(shí)間,準(zhǔn)確的提示用戶當(dāng)前是否還有商品庫(kù)存。而這些,也是需要有優(yōu)秀的程序設(shè)計(jì)來(lái)保證的。

第三:系統(tǒng)容量預(yù)估

系統(tǒng)設(shè)計(jì)的時(shí)候,都需要有一個(gè)容量預(yù)估,那就是要提前計(jì)算好,我們?cè)O(shè)計(jì)的系統(tǒng),要承載多大的數(shù)量級(jí)。

假如線上前端服務(wù)器規(guī)格是8核16G內(nèi)存的服務(wù)器,而提交訂單的處理程序耗時(shí)100ms,那么可以簡(jiǎn)單計(jì)算一下:

每秒可以處理的訂單請(qǐng)求數(shù)=1000ms/100ms*8=80qps

上面這個(gè)結(jié)果,對(duì)于秒殺系統(tǒng)來(lái)說(shuō),肯定是非常不理想的。

如果能將處理程序耗時(shí)優(yōu)化后,降低到10ms,那么就可以達(dá)到800qps。

如果我們可以把程序繼續(xù)優(yōu)化,能快速區(qū)分開有庫(kù)存和無(wú)庫(kù)存處理,那么無(wú)庫(kù)存時(shí)處理就有可能做到1ms甚至更低的耗時(shí)。這樣無(wú)庫(kù)存時(shí)就能有更好的性能,上萬(wàn)的qps也是可以達(dá)到的。

上面的預(yù)估,都是針對(duì)單機(jī),那么簡(jiǎn)單的增加前端服務(wù)器,是不是就能有更好的并發(fā)處理量呢?

肯定沒這么簡(jiǎn)單,因?yàn)閿?shù)據(jù)庫(kù)、緩存系統(tǒng)甚至機(jī)房網(wǎng)絡(luò)帶寬都會(huì)成為瓶頸。

于是就要有一個(gè)更好的分布式方案。

第四:好的分布式方案

一個(gè)好的分布式方案,首先當(dāng)然是穩(wěn)定可靠,不要出亂子,然后就是方便擴(kuò)充,最好的效果當(dāng)然是增加一臺(tái)服務(wù)器,并發(fā)處理量可以1:1線性增長(zhǎng)。

比如:?jiǎn)螜C(jī)qps是1k,那么10臺(tái)服務(wù)器可以做到1w,100臺(tái)可以做到10w每秒。

要做到這樣的線性增長(zhǎng)效果,就要杜絕出現(xiàn)瓶頸,否則還是會(huì)代價(jià)太大。

拒絕假的分布式尤其重要,比如:前端服務(wù)器是可以獨(dú)立存在的,但是都依賴集中的一個(gè)數(shù)據(jù)庫(kù)或者緩存系統(tǒng),那最后,一定是集中的那個(gè)數(shù)據(jù)庫(kù)或者緩存系統(tǒng)受不了,同樣無(wú)法做到一個(gè)好的分布式。

第五:關(guān)注系統(tǒng)的瓶頸

大家先有幾個(gè)基本的共識(shí),系統(tǒng)的處理速度

  • 程序內(nèi)數(shù)據(jù)讀寫 > redis > mysql > 磁盤
  • 單機(jī)網(wǎng)絡(luò)請(qǐng)求 > 局域網(wǎng)內(nèi)請(qǐng)求 > 跨機(jī)房請(qǐng)求

我們優(yōu)化程序的時(shí)候,盡量用最快的方式,盡量用最簡(jiǎn)短的邏輯。

用redis替代mysql來(lái)保存訂單處理中依賴的數(shù)據(jù),用程序中的提交的數(shù)據(jù)代替從redis中二次獲取數(shù)據(jù),比如:商品庫(kù)存信息,用戶訂單信息。

邏輯處理中,把速度快且提前中斷的邏輯放在最前面,比如:驗(yàn)證登錄,驗(yàn)證問答。

我們做分布式方案的時(shí)候,盡量把資源調(diào)用放在最近的地方。

前端服務(wù)器依賴的數(shù)據(jù)盡量就在局域網(wǎng)內(nèi),如果能在單機(jī)都有讀的redis服務(wù)當(dāng)然更好,程序維護(hù)數(shù)據(jù)響應(yīng)會(huì)復(fù)雜些。

不要出現(xiàn)跨機(jī)房網(wǎng)絡(luò)請(qǐng)求,不要出現(xiàn)跨機(jī)房網(wǎng)絡(luò)請(qǐng)求,不要出現(xiàn)跨機(jī)房網(wǎng)絡(luò)請(qǐng)求,重要的事情說(shuō)三遍。

第六:什么語(yǔ)言更適合這類系統(tǒng)

課程中用的是PHP語(yǔ)言,開發(fā)這類系統(tǒng)也是沒問題的。

當(dāng)然,像是用golang, ngx_lua可能在高并發(fā)和性能方面會(huì)更有優(yōu)勢(shì)。

如果使用java、.net當(dāng)然也是可以的,作為一個(gè)系統(tǒng),語(yǔ)言只是工具,更好的設(shè)計(jì)和優(yōu)化,才能達(dá)到最終想要的效果。

有了上面的基本概念,我們接下來(lái)再來(lái)看看,具體運(yùn)行時(shí),會(huì)出現(xiàn)什么狀況。

下面是一些具體的問題:

問題1:庫(kù)存超賣

只有10個(gè)庫(kù)存,但是一秒鐘有1k個(gè)訂單,怎么能不超賣呢?

核心思想就是保證庫(kù)存遞減是原子性操作,10--返回9,9--返回8,8--返回7。

而不能是讀取出來(lái)庫(kù)存10,10-1=9再更新回去。因?yàn)檫@個(gè)讀取和更新是并發(fā)執(zhí)行的,很可能就會(huì)有1k個(gè)訂單都成功了,而庫(kù)存實(shí)際只有10。

那么,怎么保證原子性操作呢?

1. 數(shù)據(jù)庫(kù):

  1. update product set left_numleft_num=left_num-1 where left_num>0; 

這里用到的是left_num=left_num-1,如果left_num>0才能執(zhí)行成功,數(shù)據(jù)庫(kù)查詢、更新的時(shí)候有用到鎖,是可以保證更新操作的原子性的。

數(shù)據(jù)庫(kù)性能較差,不建議使用。

2. 分布式鎖

用redis來(lái)做一個(gè)分布式鎖,reids->setnx('lock', 1) 設(shè)置一個(gè)鎖,程序執(zhí)行完成再del這個(gè)鎖。

鎖定的過(guò)程,不利于并發(fā)執(zhí)行,大家都在等待鎖解開,不建議使用。

3. 消息隊(duì)列

將訂單請(qǐng)求全部放入消息隊(duì)列,然后另外一個(gè)后臺(tái)程序一個(gè)個(gè)處理隊(duì)列中的訂單請(qǐng)求。

并發(fā)不受影響,但是用戶等待的時(shí)間較長(zhǎng),進(jìn)入隊(duì)列的訂單也會(huì)很多,體驗(yàn)上并不好,也不建議使用。

4. redis遞減

通過(guò) redis->incrby('product', -1) 得到遞減之后的庫(kù)存數(shù)。

性能方面很好,同時(shí)體驗(yàn)上也很好,在PHP秒殺課程中,優(yōu)化后就是用的這種方法,而沒有使用上述其他方法,大家應(yīng)該也能對(duì)比了解啦。

問題2:集群怎么來(lái)規(guī)劃

前端服務(wù)器因?yàn)闆]有相互間關(guān)聯(lián),集群的數(shù)量不受影響。

redis的性能可以達(dá)到每秒幾萬(wàn)次響應(yīng),所以一個(gè)集群的規(guī)模,也就是redis服務(wù)可以承載的數(shù)量。

比如:一臺(tái)前端服務(wù)器是1~2k的qps(有庫(kù)存時(shí)),那么10臺(tái)+1臺(tái)redis就可以是一個(gè)獨(dú)立的集群,可以支撐1~2w每秒訂單量。

10個(gè)上述的集群就可以做到一秒鐘處理10w~20w的有效訂單。

如果秒殺活動(dòng)的庫(kù)存量在1w以內(nèi),預(yù)計(jì)參與的人數(shù)在百萬(wàn)左右,那么有一個(gè)集群也就可以搞定。

如果秒殺參與的人數(shù)超過(guò)千萬(wàn),那么就要用到不止一個(gè)集群了。

問題3:多個(gè)集群的數(shù)據(jù)怎么保持一致性

不要做多集群的數(shù)據(jù)同步,而是用散列,每個(gè)集群的數(shù)據(jù)是獨(dú)立存在的。

假設(shè),有10個(gè)商品,每個(gè)商品有1w庫(kù)存,規(guī)劃用10個(gè)集群,那么每個(gè)集群有10個(gè)商品,每個(gè)商品是1k庫(kù)存。

每個(gè)集群只需要負(fù)責(zé)把自己的庫(kù)存賣掉即可,至于說(shuō),會(huì)不會(huì)有用戶知道有10個(gè)集群,然后每個(gè)集群都去搶。

這種情況就不要用程序來(lái)處理了,利用運(yùn)營(yíng)規(guī)則,活動(dòng)結(jié)束后匯總訂單的時(shí)候再去處理就好了。

如果擔(dān)心散列的不合理,比如:某個(gè)集群用戶訪問量特別少,那么可以引入一個(gè)中控服務(wù),來(lái)監(jiān)控各個(gè)集群的庫(kù)存,然后再做平衡。

問題4:機(jī)器人搶購(gòu)怎么辦:

沒什么太好的辦法,類似DDOS攻擊,只能是讓自身更強(qiáng)大才是王道。

運(yùn)營(yíng)策略上,可以嚴(yán)格控制用戶注冊(cè),必須登錄,提交訂單的時(shí)候引入圖像驗(yàn)證碼,問答,交互式驗(yàn)證等。

責(zé)任編輯:趙寧寧 來(lái)源: 今日頭條
相關(guān)推薦

2025-02-20 00:01:00

2020-10-14 07:20:53

高并發(fā)

2024-07-03 11:01:55

2020-04-13 08:33:39

高并發(fā)秒殺系統(tǒng)

2021-08-26 08:24:33

高并發(fā)秒殺系統(tǒng)

2025-01-20 00:00:03

高并發(fā)秒殺業(yè)務(wù)

2023-11-27 18:07:05

Go并發(fā)編程

2019-10-30 16:54:08

golangredis數(shù)據(jù)庫(kù)

2021-06-23 06:48:42

秒殺Java電商

2024-08-01 11:38:40

2025-04-08 05:00:00

2019-07-30 11:17:18

系統(tǒng)數(shù)據(jù)安全

2021-07-29 08:13:05

高并發(fā)秒殺商品秒殺系統(tǒng)

2022-03-18 09:11:56

高并發(fā)搶購(gòu)系統(tǒng)架構(gòu)

2019-02-15 10:11:23

2009-06-16 14:43:23

大型網(wǎng)站系統(tǒng)架構(gòu)

2021-05-24 09:28:41

軟件開發(fā) 技術(shù)

2024-09-23 08:03:13

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)