国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

高并發(fā)下秒殺商品,必須知道的9個(gè)細(xì)節(jié)

共 3829字,需瀏覽 8分鐘

 ·

2021-10-27 15:05

高并發(fā)下如何設(shè)計(jì)秒殺系統(tǒng)?這是一個(gè)高頻面試題。這個(gè)問題看似簡(jiǎn)單,但是里面的水很深,它考查的是高并發(fā)場(chǎng)景下,從前端到后端多方面的知識(shí)。

秒殺一般出現(xiàn)在商城的促銷活動(dòng)中,指定了一定數(shù)量(比如:10個(gè))的商品(比如:手機(jī)),以極低的價(jià)格(比如:0.1元),讓大量用戶參與活動(dòng),但只有極少數(shù)用戶能夠購(gòu)買成功。這類活動(dòng)商家絕大部分是不賺錢的,說(shuō)白了是找個(gè)噱頭宣傳自己。

雖說(shuō)秒殺只是一個(gè)促銷活動(dòng),但對(duì)技術(shù)要求不低。下面給大家總結(jié)一下設(shè)計(jì)秒殺系統(tǒng)需要注意的9個(gè)細(xì)節(jié)。

1 瞬時(shí)高并發(fā)

一般在秒殺時(shí)間點(diǎn)(比如:12點(diǎn))前幾分鐘,用戶并發(fā)量才真正突增,達(dá)到秒殺時(shí)間點(diǎn)時(shí),并發(fā)量會(huì)達(dá)到頂峰。

但由于這類活動(dòng)是大量用戶搶少量商品的場(chǎng)景,必定會(huì)出現(xiàn)狼多肉少的情況,所以其實(shí)絕大部分用戶秒殺會(huì)失敗,只有極少部分用戶能夠成功。

正常情況下,大部分用戶會(huì)收到商品已經(jīng)搶完的提醒,收到該提醒后,他們大概率不會(huì)在那個(gè)活動(dòng)頁(yè)面停留了,如此一來(lái),用戶并發(fā)量又會(huì)急劇下降。所以這個(gè)峰值持續(xù)的時(shí)間其實(shí)是非常短的,這樣就會(huì)出現(xiàn)瞬時(shí)高并發(fā)的情況,下面用一張圖直觀的感受一下流量的變化:

像這種瞬時(shí)高并發(fā)的場(chǎng)景,傳統(tǒng)的系統(tǒng)很難應(yīng)對(duì),我們需要設(shè)計(jì)一套全新的系統(tǒng)??梢詮囊韵聨讉€(gè)方面入手:

  1. 頁(yè)面靜態(tài)化
  2. CDN加速
  3. 緩存
  4. mq異步處理
  5. 限流
  6. 分布式鎖

2. 頁(yè)面靜態(tài)化

活動(dòng)頁(yè)面是用戶流量的第一入口,所以是并發(fā)量最大的地方。

如果這些流量都能直接訪問服務(wù)端,恐怕服務(wù)端會(huì)因?yàn)槌惺懿蛔∵@么大的壓力,而直接掛掉。

活動(dòng)頁(yè)面絕大多數(shù)內(nèi)容是固定的,比如:商品名稱、商品描述、圖片等。為了減少不必要的服務(wù)端請(qǐng)求,通常情況下,會(huì)對(duì)活動(dòng)頁(yè)面做靜態(tài)化處理。用戶瀏覽商品等常規(guī)操作,并不會(huì)請(qǐng)求到服務(wù)端。只有到了秒殺時(shí)間點(diǎn),并且用戶主動(dòng)點(diǎn)了秒殺按鈕才允許訪問服務(wù)端。

這樣能過濾大部分無(wú)效請(qǐng)求。

但只做頁(yè)面靜態(tài)化還不夠,因?yàn)橛脩舴植荚谌珖?guó)各地,有些人在北京,有些人在成都,有些人在深圳,地域相差很遠(yuǎn),網(wǎng)速各不相同。

如何才能讓用戶最快訪問到活動(dòng)頁(yè)面呢?

這就需要使用CDN,它的全稱是Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。

使用戶就近獲取所需內(nèi)容,降低網(wǎng)絡(luò)擁塞,提高用戶訪問響應(yīng)速度和命中率。

3 秒殺按鈕

大部分用戶怕錯(cuò)過秒殺時(shí)間點(diǎn),一般會(huì)提前進(jìn)入活動(dòng)頁(yè)面。此時(shí)看到的秒殺按鈕是置灰,不可點(diǎn)擊的。只有到了秒殺時(shí)間點(diǎn)那一時(shí)刻,秒殺按鈕才會(huì)自動(dòng)點(diǎn)亮,變成可點(diǎn)擊的。

但此時(shí)很多用戶已經(jīng)迫不及待了,通過不停刷新頁(yè)面,爭(zhēng)取在第一時(shí)間看到秒殺按鈕的點(diǎn)亮。

從前面得知,該活動(dòng)頁(yè)面是靜態(tài)的。那么我們?cè)陟o態(tài)頁(yè)面中如何控制秒殺按鈕,只在秒殺時(shí)間點(diǎn)時(shí)才點(diǎn)亮呢?

沒錯(cuò),使用js文件控制。

為了性能考慮,一般會(huì)將css、js和圖片等靜態(tài)資源文件提前緩存到CDN上,讓用戶能夠就近訪問秒殺頁(yè)面。

看到這里,有些聰明的小伙伴,可能會(huì)問:CDN上的js文件是如何更新的?

秒殺開始之前,js標(biāo)志為false,還有另外一個(gè)隨機(jī)參數(shù)。當(dāng)秒殺開始的時(shí)候系統(tǒng)會(huì)生成一個(gè)新的js文件,此時(shí)標(biāo)志為true,并且隨機(jī)參數(shù)生成一個(gè)新值,然后同步給CDN。由于有了這個(gè)隨機(jī)參數(shù),CDN不會(huì)緩存數(shù)據(jù),每次都能從CDN中獲取最新的js代碼。此外,前端還可以加一個(gè)定時(shí)器,控制比如:10秒之內(nèi),只允許發(fā)起一次請(qǐng)求。如果用戶點(diǎn)擊了一次秒殺按鈕,則在10秒之內(nèi)置灰,不允許再次點(diǎn)擊,等到過了時(shí)間限制,又允許重新點(diǎn)擊該按鈕。

4 讀多寫少

在秒殺的過程中,系統(tǒng)一般會(huì)先查一下庫(kù)存是否足夠,如果足夠才允許下單,寫數(shù)據(jù)庫(kù)。如果不夠,則直接返回該商品已經(jīng)搶完。

由于大量用戶搶少量商品,只有極少部分用戶能夠搶成功,所以絕大部分用戶在秒殺時(shí),庫(kù)存其實(shí)是不足的,系統(tǒng)會(huì)直接返回該商品已經(jīng)搶完。

這是非常典型的:讀多寫少 的場(chǎng)景。

如果有數(shù)十萬(wàn)的請(qǐng)求過來(lái),同時(shí)通過數(shù)據(jù)庫(kù)查緩存是否足夠,此時(shí)數(shù)據(jù)庫(kù)可能會(huì)掛掉。因?yàn)閿?shù)據(jù)庫(kù)的連接資源非常有限,比如:mysql,無(wú)法同時(shí)支持這么多的連接。

而應(yīng)該改用緩存,比如:redis。

即便用了redis,也需要部署多個(gè)節(jié)點(diǎn)。

5 緩存問題

通常情況下,我們需要在redis中保存商品信息,里面包含:商品id、商品名稱、規(guī)格屬性、庫(kù)存等信息,同時(shí)數(shù)據(jù)庫(kù)中也要有相關(guān)信息,畢竟緩存并不完全可靠。

用戶在點(diǎn)擊秒殺按鈕,請(qǐng)求秒殺接口的過程中,需要傳入的商品id參數(shù),然后服務(wù)端需要校驗(yàn)該商品是否合法。

大致流程如下圖所示:

根據(jù)商品id,先從緩存中查詢商品,如果商品存在,則參與秒殺。如果不存在,則需要從數(shù)據(jù)庫(kù)中查詢商品,如果存在,則將商品信息放入緩存,然后參與秒殺。如果商品不存在,則直接提示失敗。

這個(gè)過程表面上看起來(lái)是OK的,但是如果深入分析一下會(huì)發(fā)現(xiàn)一些問題。

5.1 緩存擊穿

比如商品A第一次秒殺時(shí),緩存中是沒有數(shù)據(jù)的,但數(shù)據(jù)庫(kù)中有。雖說(shuō)上面有如果從數(shù)據(jù)庫(kù)中查到數(shù)據(jù),則放入緩存的邏輯。

然而,在高并發(fā)下,同一時(shí)刻會(huì)有大量的請(qǐng)求,都在秒殺同一件商品,這些請(qǐng)求同時(shí)去查緩存中沒有數(shù)據(jù),然后又同時(shí)訪問數(shù)據(jù)庫(kù)。結(jié)果悲劇了,數(shù)據(jù)庫(kù)可能扛不住壓力,直接掛掉。

如何解決這個(gè)問題呢?

這就需要加鎖,最好使用分布式鎖。

當(dāng)然,針對(duì)這種情況,最好在項(xiàng)目啟動(dòng)之前,先把緩存進(jìn)行預(yù)熱。即事先把所有的商品,同步到緩存中,這樣商品基本都能直接從緩存中獲取到,就不會(huì)出現(xiàn)緩存擊穿的問題了。

是不是上面加鎖這一步可以不需要了?

表面上看起來(lái),確實(shí)可以不需要。但如果緩存中設(shè)置的過期時(shí)間不對(duì),緩存提前過期了,或者緩存被不小心刪除了,如果不加速同樣可能出現(xiàn)緩存擊穿。

其實(shí)這里加鎖,相當(dāng)于買了一份保險(xiǎn)。

5.2 緩存穿透

如果有大量的請(qǐng)求傳入的商品id,在緩存中和數(shù)據(jù)庫(kù)中都不存在,這些請(qǐng)求不就每次都會(huì)穿透過緩存,而直接訪問數(shù)據(jù)庫(kù)了。

由于前面已經(jīng)加了鎖,所以即使這里的并發(fā)量很大,也不會(huì)導(dǎo)致數(shù)據(jù)庫(kù)直接掛掉。

但很顯然這些請(qǐng)求的處理性能并不好,有沒有更好的解決方案?

這時(shí)可以想到布隆過濾器。

系統(tǒng)根據(jù)商品id,先從布隆過濾器中查詢?cè)搃d是否存在,如果存在則允許從緩存中查詢數(shù)據(jù),如果不存在,則直接返回失敗。

雖說(shuō)該方案可以解決緩存穿透問題,但是又會(huì)引出另外一個(gè)問題:布隆過濾器中的數(shù)據(jù)如何更緩存中的數(shù)據(jù)保持一致?

這就要求,如果緩存中數(shù)據(jù)有更新,則要及時(shí)同步到布隆過濾器中。如果數(shù)據(jù)同步失敗了,還需要增加重試機(jī)制,而且跨數(shù)據(jù)源,能保證數(shù)據(jù)的實(shí)時(shí)一致性嗎?

顯然是不行的。

所以布隆過濾器絕大部分使用在緩存數(shù)據(jù)更新很少的場(chǎng)景中。

如果緩存數(shù)據(jù)更新非常頻繁,又該如何處理呢?

這時(shí),就需要把不存在的商品id也緩存起來(lái)。

下次,再有該商品id的請(qǐng)求過來(lái),則也能從緩存中查到數(shù)據(jù),只不過該數(shù)據(jù)比較特殊,表示商品不存在。需要特別注意的是,這種特殊緩存設(shè)置的超時(shí)時(shí)間應(yīng)該盡量短一點(diǎn)。

6 庫(kù)存問題

對(duì)于庫(kù)存問題看似簡(jiǎn)單,實(shí)則里面還是有些東西。

真正的秒殺商品的場(chǎng)景,不是說(shuō)扣完庫(kù)存,就完事了,如果用戶在一段時(shí)間內(nèi),還沒完成支付,扣減的庫(kù)存是要加回去的。

所以,在這里引出了一個(gè)預(yù)扣庫(kù)存的概念,預(yù)扣庫(kù)存的主要流程如下:

扣減庫(kù)存中除了上面說(shuō)到的預(yù)扣庫(kù)存回退庫(kù)存之外,還需要特別注意的是庫(kù)存不足和庫(kù)存超賣問題。

6.1 數(shù)據(jù)庫(kù)扣減庫(kù)存

使用數(shù)據(jù)庫(kù)扣減庫(kù)存,是最簡(jiǎn)單的實(shí)現(xiàn)方案了,假設(shè)扣減庫(kù)存的sql如下:

update?product?set?stock=stock-1?where?id=123;

這種寫法對(duì)于扣減庫(kù)存是沒有問題的,但如何控制庫(kù)存不足的情況下,不讓用戶操作呢?

這就需要在update之前,先查一下庫(kù)存是否足夠了。

偽代碼如下:

int?stock?=?mapper.getStockById(123);
if(stock?>?0)?{
??int?count?=?mapper.updateStock(123);
??if(count?>?0)?{
????addOrder(123);
??}
}

大家有沒有發(fā)現(xiàn)這段代碼的問題?

沒錯(cuò),查詢操作和更新操作不是原子性的,會(huì)導(dǎo)致在并發(fā)的場(chǎng)景下,出現(xiàn)庫(kù)存超賣的情況。

有人可能會(huì)說(shuō),這樣好辦,加把鎖,不就搞定了,比如使用synchronized關(guān)鍵字。

確實(shí),可以,但是性能不夠好。

還有更優(yōu)雅的處理方案,即基于數(shù)據(jù)庫(kù)的樂觀鎖,這樣會(huì)少一次數(shù)據(jù)庫(kù)查詢,而且能夠天然的保證數(shù)據(jù)操作的原子性。

只需將上面的sql稍微調(diào)整一下:

update?product?set?stock=stock-1?where?id=product?and?stock?>?0;

在sql最后加上:stock > 0,就能保證不會(huì)出現(xiàn)超賣的情況。

但需要頻繁訪問數(shù)據(jù)庫(kù),我們都知道數(shù)據(jù)庫(kù)連接是非常昂貴的資源。在高并發(fā)的場(chǎng)景下,可能會(huì)造成系統(tǒng)雪崩。而且,容易出現(xiàn)多個(gè)請(qǐng)求,同時(shí)競(jìng)爭(zhēng)行鎖的情況,造成相互等待,從而出現(xiàn)死鎖的問題。

6.2 redis扣減庫(kù)存

redis的incr方法是原子性的,可以用該方法扣減庫(kù)存。偽代碼如下:

 boolean?exist?=?redisClient.query(productId,userId);
??if(exist)?{
????return?-1;
??}
??int?stock?=?redisClient.queryStock(productId);
??if(stock?<=0)?{
????return?0;
??}
??redisClient.incrby(productId,?-1);
??redisClient.add(productId,userId);
return?1;

代碼流程如下:

  1. 先判斷該用戶有沒有秒殺過該商品,如果已經(jīng)秒殺過,則直接返回-1。
  2. 查詢庫(kù)存,如果庫(kù)存小于等于0,則直接返回0,表示庫(kù)存不足。
  3. 如果庫(kù)存充足,則扣減庫(kù)存,然后將本次秒殺記錄保存起來(lái)。然后返回1,表示成功。

估計(jì)很多小伙伴,一開始都會(huì)按這樣的思路寫代碼。但如果仔細(xì)想想會(huì)發(fā)現(xiàn),這段代碼有問題。

有什么問題呢?

如果在高并發(fā)下,有多個(gè)請(qǐng)求同時(shí)查詢庫(kù)存,當(dāng)時(shí)都大于0。由于查詢庫(kù)存和更新庫(kù)存非原則操作,則會(huì)出現(xiàn)庫(kù)存為負(fù)數(shù)的情況,即庫(kù)存超賣。

當(dāng)然有人可能會(huì)說(shuō),加個(gè)synchronized不就解決問題?

調(diào)整后代碼如下:

???boolean?exist?=?redisClient.query(productId,userId);
???if(exist)?{
????return?-1;
???}
???synchronized(this)?{
???????int?stock?=?redisClient.queryStock(productId);
???????if(stock?<=0)?{
?????????return?0;
???????}
???????redisClient.incrby(productId,?-1);
???????redisClient.add(productId,userId);
???}

return?1;

synchronized確實(shí)能解決庫(kù)存為負(fù)數(shù)問題,但是這樣會(huì)導(dǎo)致接口性能急劇下降,每次查詢都需要競(jìng)爭(zhēng)同一把鎖,顯然不太合理。

為了解決上面的問題,代碼優(yōu)化如下:

boolean?exist?=?redisClient.query(productId,userId);
if(exist)?{
??return?-1;
}
if(redisClient.incrby(productId,?-1)<0)?{
??return?0;
}
redisClient.add(productId,userId);
return?1;

該代碼主要流程如下:

  1. 先判斷該用戶有沒有秒殺過該商品,如果已經(jīng)秒殺過,則直接返回-1。
  2. 扣減庫(kù)存,判斷返回值是否小于0,如果小于0,則直接返回0,表示庫(kù)存不足。
  3. 如果扣減庫(kù)存后,返回值大于或等于0,則將本次秒殺記錄保存起來(lái)。然后返回1,表示成功。

該方案咋一看,好像沒問題。

但如果在高并發(fā)場(chǎng)景中,有多個(gè)請(qǐng)求同時(shí)扣減庫(kù)存,大多數(shù)請(qǐng)求的incrby操作之后,結(jié)果都會(huì)小于0。

雖說(shuō),庫(kù)存出現(xiàn)負(fù)數(shù),不會(huì)出現(xiàn)超賣的問題。但由于這里是預(yù)減庫(kù)存,如果負(fù)數(shù)值負(fù)的太多的話,后面萬(wàn)一要回退庫(kù)存時(shí),就會(huì)導(dǎo)致庫(kù)存不準(zhǔn)。

那么,有沒有更好的方案呢?

6.3 lua腳本扣減庫(kù)存

我們都知道lua腳本,是能夠保證原子性的,它跟redis一起配合使用,能夠完美解決上面的問題。

lua腳本有段非常經(jīng)典的代碼:

??StringBuilder?lua?=?new?StringBuilder();
??lua.append("if?(redis.call('exists',?KEYS[1])?==?1)?then");
??lua.append("????local?stock?=?tonumber(redis.call('get',?KEYS[1]));");
??lua.append("????if?(stock?==?-1)?then");
??lua.append("????????return?1;");
??lua.append("????end;");
??lua.append("????if?(stock?>?0)?then");
??lua.append("????????redis.call('incrby',?KEYS[1],?-1);");
??lua.append("????????return?stock;");
??lua.append("????end;");
??lua.append("????return?0;");
??lua.append("end;");
??lua.append("return?-1;");

該代碼的主要流程如下:

  1. 先判斷商品id是否存在,如果不存在則直接返回。
  2. 獲取該商品id的庫(kù)存,判斷庫(kù)存如果是-1,則直接返回,表示不限制庫(kù)存。
  3. 如果庫(kù)存大于0,則扣減庫(kù)存。
  4. 如果庫(kù)存等于0,是直接返回,表示庫(kù)存不足。

7 分布式鎖

之前我提到過,在秒殺的時(shí)候,需要先從緩存中查商品是否存在,如果不存在,則會(huì)從數(shù)據(jù)庫(kù)中查商品。如果數(shù)據(jù)庫(kù)中,則將該商品放入緩存中,然后返回。如果數(shù)據(jù)庫(kù)中沒有,則直接返回失敗。


大家試想一下,如果在高并發(fā)下,有大量的請(qǐng)求都去查一個(gè)緩存中不存在的商品,這些請(qǐng)求都會(huì)直接打到數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)由于承受不住壓力,而直接掛掉。


那么如何解決這個(gè)問題呢?


這就需要用redis分布式鎖了。

7.1 setNx加鎖

使用redis的分布式鎖,首先想到的是setNx命令。

if?(jedis.setnx(lockKey,?val)?==?1)?{
???jedis.expire(lockKey,?timeout);
}

用該命令其實(shí)可以加鎖,但和后面的設(shè)置超時(shí)時(shí)間是分開的,并非原子操作。

假如加鎖成功了,但是設(shè)置超時(shí)時(shí)間失敗了,該lockKey就變成永不失效的了。在高并發(fā)場(chǎng)景中,該問題會(huì)導(dǎo)致非常嚴(yán)重的后果。

那么,有沒有保證原子性的加鎖命令呢?

7.2 set加鎖

使用redis的set命令,它可以指定多個(gè)參數(shù)。

String?result?=?jedis.set(lockKey,?requestId,?"NX",?"PX",?expireTime);
if?("OK".equals(result))?{
????return?true;
}
return?false;

其中:

  • lockKey:鎖的標(biāo)識(shí)
  • requestId:請(qǐng)求id
  • NX:只在鍵不存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作。
  • PX:設(shè)置鍵的過期時(shí)間為 millisecond 毫秒。
  • expireTime:過期時(shí)間


由于該命令只有一步,所以它是原子操作。

7.3 釋放鎖

接下來(lái),有些朋友可能會(huì)問:在加鎖時(shí),既然已經(jīng)有了lockKey鎖標(biāo)識(shí),為什么要需要記錄requestId呢?

答:requestId是在釋放鎖的時(shí)候用的。

if?(jedis.get(lockKey).equals(requestId))?{
????jedis.del(lockKey);
????return?true;
}
return?false;

在釋放鎖的時(shí)候,只能釋放自己加的鎖,不允許釋放別人加的鎖。

這里為什么要用requestId,用userId不行嗎?

答:如果用userId的話,假設(shè)本次請(qǐng)求流程走完了,準(zhǔn)備刪除鎖。此時(shí),巧合鎖到了過期時(shí)間失效了。而另外一個(gè)請(qǐng)求,巧合使用的相同userId加鎖,會(huì)成功。而本次請(qǐng)求刪除鎖的時(shí)候,刪除的其實(shí)是別人的鎖了。

當(dāng)然使用lua腳本也能避免該問題:

if?redis.call('get',?KEYS[1])?==?ARGV[1]?then?
?return?redis.call('del',?KEYS[1])?
else?
??return?0?
end

它能保證查詢鎖是否存在和刪除鎖是原子操作。

7.4 自旋鎖

上面的加鎖方法看起來(lái)好像沒有問題,但如果你仔細(xì)想想,如果有1萬(wàn)的請(qǐng)求同時(shí)去競(jìng)爭(zhēng)那把鎖,可能只有一個(gè)請(qǐng)求是成功的,其余的9999個(gè)請(qǐng)求都會(huì)失敗。

在秒殺場(chǎng)景下,會(huì)有什么問題?

答:每1萬(wàn)個(gè)請(qǐng)求,有1個(gè)成功。再1萬(wàn)個(gè)請(qǐng)求,有1個(gè)成功。如此下去,直到庫(kù)存不足。這就變成均勻分布的秒殺了,跟我們想象中的不一樣。

如何解決這個(gè)問題呢?

答:使用自旋鎖。

try?{
??Long?start?=?System.currentTimeMillis();
??while(true)?{
??????String?result?=?jedis.set(lockKey,?requestId,?"NX",?"PX",?expireTime);
?????if?("OK".equals(result))?{
????????return?true;
?????}
?????
?????long?time?=?System.currentTimeMillis()?-?start;
??????if?(time>=timeout)?{
??????????return?false;
??????}
??????try?{
??????????Thread.sleep(50);
??????}?catch?(InterruptedException?e)?{
??????????e.printStackTrace();
??????}
??}
?
}?finally{
????unlock(lockKey,requestId);
}??
return?false;

在規(guī)定的時(shí)間,比如500毫秒內(nèi),自旋不斷嘗試加鎖,如果成功則直接返回。如果失敗,則休眠50毫秒,再發(fā)起新一輪的嘗試。如果到了超時(shí)時(shí)間,還未加鎖成功,則直接返回失敗。

7.5 redisson

除了上面的問題之外,使用redis分布式鎖,還有鎖競(jìng)爭(zhēng)問題、續(xù)期問題、鎖重入問題、多個(gè)redis實(shí)例加鎖問題等。

這些問題使用redisson可以解決,由于篇幅的原因,在這里先保留一點(diǎn)懸念,有疑問的私聊給我。后面會(huì)出一個(gè)專題介紹分布式鎖,敬請(qǐng)期待。

8 mq異步處理

我們都知道在真實(shí)的秒殺場(chǎng)景中,有三個(gè)核心流程:而這三個(gè)核心流程中,真正并發(fā)量大的是秒殺功能,下單和支付功能實(shí)際并發(fā)量很小。所以,我們?cè)谠O(shè)計(jì)秒殺系統(tǒng)時(shí),有必要把下單和支付功能從秒殺的主流程中拆分出來(lái),特別是下單功能要做成mq異步處理的。而支付功能,比如支付寶支付,是業(yè)務(wù)場(chǎng)景本身保證的異步。

于是,秒殺后下單的流程變成如下:如果使用mq,需要關(guān)注以下幾個(gè)問題:

8.1 消息丟失問題

秒殺成功了,往mq發(fā)送下單消息的時(shí)候,有可能會(huì)失敗。原因有很多,比如:網(wǎng)絡(luò)問題、broker掛了、mq服務(wù)端磁盤問題等。這些情況,都可能會(huì)造成消息丟失。

那么,如何防止消息丟失呢?

答:加一張消息發(fā)送表。

在生產(chǎn)者發(fā)送mq消息之前,先把該條消息寫入消息發(fā)送表,初始狀態(tài)是待處理,然后再發(fā)送mq消息。消費(fèi)者消費(fèi)消息時(shí),處理完業(yè)務(wù)邏輯之后,再回調(diào)生產(chǎn)者的一個(gè)接口,修改消息狀態(tài)為已處理。

如果生產(chǎn)者把消息寫入消息發(fā)送表之后,再發(fā)送mq消息到mq服務(wù)端的過程中失敗了,造成了消息丟失。

這時(shí)候,要如何處理呢?

答:使用job,增加重試機(jī)制。

用job每隔一段時(shí)間去查詢消息發(fā)送表中狀態(tài)為待處理的數(shù)據(jù),然后重新發(fā)送mq消息。

8.2 重復(fù)消費(fèi)問題

本來(lái)消費(fèi)者消費(fèi)消息時(shí),在ack應(yīng)答的時(shí)候,如果網(wǎng)絡(luò)超時(shí),本身就可能會(huì)消費(fèi)重復(fù)的消息。但由于消息發(fā)送者增加了重試機(jī)制,會(huì)導(dǎo)致消費(fèi)者重復(fù)消息的概率增大。

那么,如何解決重復(fù)消息問題呢?

答:加一張消息處理表。

消費(fèi)者讀到消息之后,先判斷一下消息處理表,是否存在該消息,如果存在,表示是重復(fù)消費(fèi),則直接返回。如果不存在,則進(jìn)行下單操作,接著將該消息寫入消息處理表中,再返回。

有個(gè)比較關(guān)鍵的點(diǎn)是:下單和寫消息處理表,要放在同一個(gè)事務(wù)中,保證原子操作。

8.3 垃圾消息問題

這套方案表面上看起來(lái)沒有問題,但如果出現(xiàn)了消息消費(fèi)失敗的情況。比如:由于某些原因,消息消費(fèi)者下單一直失敗,一直不能回調(diào)狀態(tài)變更接口,這樣job會(huì)不停的重試發(fā)消息。最后,會(huì)產(chǎn)生大量的垃圾消息。

那么,如何解決這個(gè)問題呢?每次在job重試時(shí),需要先判斷一下消息發(fā)送表中該消息的發(fā)送次數(shù)是否達(dá)到最大限制,如果達(dá)到了,則直接返回。如果沒有達(dá)到,則將次數(shù)加1,然后發(fā)送消息。

這樣如果出現(xiàn)異常,只會(huì)產(chǎn)生少量的垃圾消息,不會(huì)影響到正常的業(yè)務(wù)。

8.4 延遲消費(fèi)問題

通常情況下,如果用戶秒殺成功了,下單之后,在15分鐘之內(nèi)還未完成支付的話,該訂單會(huì)被自動(dòng)取消,回退庫(kù)存。

那么,在15分鐘內(nèi)未完成支付,訂單被自動(dòng)取消的功能,要如何實(shí)現(xiàn)呢?

我們首先想到的可能是job,因?yàn)樗容^簡(jiǎn)單。

但job有個(gè)問題,需要每隔一段時(shí)間處理一次,實(shí)時(shí)性不太好。

還有更好的方案?

答:使用延遲隊(duì)列。

我們都知道rocketmq,自帶了延遲隊(duì)列的功能。

下單時(shí)消息生產(chǎn)者會(huì)先生成訂單,此時(shí)狀態(tài)為待支付,然后會(huì)向延遲隊(duì)列中發(fā)一條消息。達(dá)到了延遲時(shí)間,消息消費(fèi)者讀取消息之后,會(huì)查詢?cè)撚唵蔚臓顟B(tài)是否為待支付。如果是待支付狀態(tài),則會(huì)更新訂單狀態(tài)為取消狀態(tài)。如果不是待支付狀態(tài),說(shuō)明該訂單已經(jīng)支付過了,則直接返回。

還有個(gè)關(guān)鍵點(diǎn),用戶完成支付之后,會(huì)修改訂單狀態(tài)為已支付。

9 如何限流?

通過秒殺活動(dòng),如果我們運(yùn)氣爆棚,可能會(huì)用非常低的價(jià)格買到不錯(cuò)的商品(這種概率堪比買福利彩票中大獎(jiǎng))。

但有些高手,并不會(huì)像我們一樣老老實(shí)實(shí),通過秒殺頁(yè)面點(diǎn)擊秒殺按鈕,搶購(gòu)商品。他們可能在自己的服務(wù)器上,模擬正常用戶登錄系統(tǒng),跳過秒殺頁(yè)面,直接調(diào)用秒殺接口。

如果是我們手動(dòng)操作,一般情況下,一秒鐘只能點(diǎn)擊一次秒殺按鈕。但是如果是服務(wù)器,一秒鐘可以請(qǐng)求成上千接口。這種差距實(shí)在太明顯了,如果不做任何限制,絕大部分商品可能是被機(jī)器搶到,而非正常的用戶,有點(diǎn)不太公平。

所以,我們有必要識(shí)別這些非法請(qǐng)求,做一些限制。那么,我們?cè)撊绾维F(xiàn)在這些非法請(qǐng)求呢?

目前有兩種常用的限流方式:

  1. 基于nginx限流
  2. 基于redis限流

9.1 對(duì)同一用戶限流

為了防止某個(gè)用戶,請(qǐng)求接口次數(shù)過于頻繁,可以只針對(duì)該用戶做限制。限制同一個(gè)用戶id,比如每分鐘只能請(qǐng)求5次接口。

9.2 對(duì)同一ip限流

有時(shí)候只對(duì)某個(gè)用戶限流是不夠的,有些高手可以模擬多個(gè)用戶請(qǐng)求,這種nginx就沒法識(shí)別了。

這時(shí)需要加同一ip限流功能。限制同一個(gè)ip,比如每分鐘只能請(qǐng)求5次接口。

但這種限流方式可能會(huì)有誤殺的情況,比如同一個(gè)公司或網(wǎng)吧的出口ip是相同的,如果里面有多個(gè)正常用戶同時(shí)發(fā)起請(qǐng)求,有些用戶可能會(huì)被限制住。

9.3 對(duì)接口限流

別以為限制了用戶和ip就萬(wàn)事大吉,有些高手甚至可以使用代理,每次都請(qǐng)求都換一個(gè)ip。

這時(shí)可以限制請(qǐng)求的接口總次數(shù)。在高并發(fā)場(chǎng)景下,這種限制對(duì)于系統(tǒng)的穩(wěn)定性是非常有必要的。但可能由于有些非法請(qǐng)求次數(shù)太多,達(dá)到了該接口的請(qǐng)求上限,而影響其他的正常用戶訪問該接口??雌饋?lái)有點(diǎn)得不償失。

9.4 加驗(yàn)證碼

相對(duì)于上面三種方式,加驗(yàn)證碼的方式可能更精準(zhǔn)一些,同樣能限制用戶的訪問頻次,但好處是不會(huì)存在誤殺的情況。

通常情況下,用戶在請(qǐng)求之前,需要先輸入驗(yàn)證碼。用戶發(fā)起請(qǐng)求之后,服務(wù)端會(huì)去校驗(yàn)該驗(yàn)證碼是否正確。只有正確才允許進(jìn)行下一步操作,否則直接返回,并且提示驗(yàn)證碼錯(cuò)誤。

此外,驗(yàn)證碼一般是一次性的,同一個(gè)驗(yàn)證碼只允許使用一次,不允許重復(fù)使用。

普通驗(yàn)證碼,由于生成的數(shù)字或者圖案比較簡(jiǎn)單,可能會(huì)被破解。優(yōu)點(diǎn)是生成速度比較快,缺點(diǎn)是有安全隱患。

還有一個(gè)驗(yàn)證碼叫做:移動(dòng)滑塊,它生成速度比較慢,但比較安全,是目前各大互聯(lián)網(wǎng)公司的首選。

9.5 提高業(yè)務(wù)門檻

上面說(shuō)的加驗(yàn)證碼雖然可以限制非法用戶請(qǐng)求,但是有些影響用戶體驗(yàn)。用戶點(diǎn)擊秒殺按鈕前,還要先輸入驗(yàn)證碼,流程顯得有點(diǎn)繁瑣,秒殺功能的流程不是應(yīng)該越簡(jiǎn)單越好嗎?

其實(shí),有時(shí)候達(dá)到某個(gè)目的,不一定非要通過技術(shù)手段,通過業(yè)務(wù)手段也一樣。

12306剛開始的時(shí)候,全國(guó)人民都在同一時(shí)刻搶火車票,由于并發(fā)量太大,系統(tǒng)經(jīng)常掛。后來(lái),重構(gòu)優(yōu)化之后,將購(gòu)買周期放長(zhǎng)了,可以提前20天購(gòu)買火車票,并且可以在9點(diǎn)、10、11點(diǎn)、12點(diǎn)等整點(diǎn)購(gòu)買火車票。調(diào)整業(yè)務(wù)之后(當(dāng)然技術(shù)也有很多調(diào)整),將之前集中的請(qǐng)求,分散開了,一下子降低了用戶并發(fā)量。

回到這里,我們通過提高業(yè)務(wù)門檻,比如只有會(huì)員才能參與秒殺活動(dòng),普通注冊(cè)用戶沒有權(quán)限?;蛘撸挥械燃?jí)到達(dá)3級(jí)以上的普通用戶,才有資格參加該活動(dòng)。

這樣簡(jiǎn)單的提高一點(diǎn)門檻,即使是黃牛黨也束手無(wú)策,他們總不可能為了參加一次秒殺活動(dòng),還另外花錢充值會(huì)員吧?


最后說(shuō)一句(求關(guān)注,別白嫖我)

如果這篇文章對(duì)您有所幫助,或者有所啟發(fā)的話,幫忙掃描下發(fā)二維碼關(guān)注一下,您的支持是我堅(jiān)持寫作最大的動(dòng)力。

求一鍵三連:點(diǎn)贊、轉(zhuǎn)發(fā)、在看。

瀏覽 43
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)
評(píng)論
圖片
表情
推薦
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 91网在线| 高清无码在线视频观看| 天天射天天爽| 色999在线播放视频| 美女91小视频| 国产一区二区三区视频在线观看| 手机不卡黄色视频在线| 草逼123| 人妻无码久久| 91麻豆国产在线观看| 国产精品99精品| 黄色小视频在线免费观看| 江苏妇搡BBBB搡BBBB-百度| 亚洲高清无码视频在线播放| 在线免费看a| 无码人妻日韩精品一区二区三| 另类欧美| 暗呦网一区二区三区| 成人a片在线免费观看| 男女操逼视频网站| 一区二区三区不卡视频| 91久久人澡人妻人人澡人人爽 | 天天爱av| 在线观看的av| 黄一区二区| 欧美日韩国产精品成人| 欧洲黑人成人A版免费视频| AV大片在线观看| 成人免费网站| 91精品国产综合久久久蜜臀粉嫩 | 色中文字幕| 蜜臀久久99久久久久久宅男| 91丨PORNY丨丰满人妻网站| 日本一级特黄电影| 少妇AV| 亚洲最大黄色| 在线看v片| 天天日天天射天天干| 国产老女人操逼视频| 国产精品成人在线观看| 大香蕉最新国产2025| 欧美性猛交XXXX乱大交HD| 超碰狠狠操| 四虎成人精品永久免费AV九九| 欧美日韩日逼| 亲子乱婬-一级A片| 九色国产视频| 五月天在线电影| 69成人免费视频| 精品看片| 欧美五月激情| 91熟女首页| 香蕉AV777XXX色综合一区| 日韩免费高清在线视频| 免费一级大片| 欧美色图视频网站| 再深点好爽灬轻点久久国产| 国产免费成人| 亚洲一级免费视频| 蜜桃高清无码| 伊人网大香| 日韩欧美国产成人| 一级欧美| 竹菊av一区二区三区四区五区| 欧美日韩99| 91视频在线免费观看app| 人人干人人操人人摸| 国产精品黑人ThePorn| 日本亚洲黄色视频| 夜夜夜夜撸| 香蕉久久a毛片| 人人摸人人爱人人操| 老欧性老太色HD大全| 翔田千里在线观看| 国产啊啊啊| 日韩网站在线观看| 佳佳女王footjob超级爽| AV中文无码| 国产精品久久久久永久免费看| 欧美不卡一区二区| 黄色视频在线观看网站| 蜜桃传媒av| 神马午夜av| 91久久精品一区二区三| 亚洲插逼视频| 亚洲成人在线网站| 国产真实乱婬A片久久久老牛| 国产色视频| 日韩在线看片| 五月婷婷影院| 亚洲九九视频| 精品人妻中文字幕视频| 天天色情| 懂色av蜜臀av粉嫩av分| 成人网在线视频| 亚洲人操逼视频| 国产精品无码久久久久成人app | 国产一区二区免费| 翔田千里无码视频| 成人自拍视频在线观看| 日本黄色高清视频| 夜夜撸| 女人18片毛片60分钟黃菲菲| 操B视频在线播放| 少妇搡BBBB搡BBBB毛多多| 国产Av影视| 婷婷国产成人精品| 亚洲视频免费播放| 国内精品内射| 天天色网站| 中文字幕熟女人妻| 黄色毛片在线| 国产色黄视频| 日韩一级a| 日韩无码操逼| 亚洲精品国产成人| 超碰在线中文字幕| 在线A视频| 韩日综合在线| 亚洲无码高清视频| 精品码一区二在线观看| 黄色视频日本免费| 黑丝一区| 成人免费大香蕉| 夜夜爽妓女77777毛片A片| 高清无码一区二区在线| 成人亚洲| 国产欧美成人| 亚洲AV成人无码一区二区三区| 中文字幕乱码亚洲无线码按摩| 亚洲激情av| 俺来俺也去www色在线观看| 日本家庭乱伦视频| www黄片| 国产亲子乱XXXXinin| 大色AV| 久久6热| 免费黄色在线视频| 人人澡人人澡人人| 国产三级精品三级在线观看| 激情aaa| 日韩AV在线电影| 欧美性爱xxxx| 国内精品久久久久久久久久| 白丝久久| 人人色人人摸| 国产成人无码免费看片| 久久婷婷国产麻豆91天堂| 国产精品精品| 日本少妇午夜福利| 色二区| 日韩三级AV| 91人人妻人人爽| 色av影音先锋无吗一区| 泄火熟妇2-ThePorn| 亚洲成人AV在线播放| 强伦轩一区二区三区在线观看| 中文字幕在线播放AV| 99爱视频| 成人做爰黄A片免费看直播室动漫| 国产精品婷婷久久久| 欧美日韩北条麻妃视频在线观看| 婷婷激情中文字幕| 中文字幕无码在线| 偷拍第一页| 熟妇人妻丰满久久久久久久无码 | 久肏| 人人看人人搂人人摸| 国产av小电影| 男人的天堂视频在线观看| 北条麻妃无码| 精品A片| 成人无码一区二区三区| 欧美成年人网站| 亚洲第一成年人网站| 五月丁香在线播放| 国产精品久久久一区二区三区 | 97自拍| 高清无码日本| 中文字幕12页| 久久伊人亚洲| 91综合色| 亚洲天堂2014| 褒姒AV无玛| 久久久亚洲无码| 国产福利精品视频| 成人国产精品在线看| 一级特黄录像免费播放下载软件| 久久国产精品精品国产色婷婷| 欧美三级性爱视频| 三级日韩| 亚卅毛片| 欧美日日| www.黄片| 日韩视频免费观看| 久草视频免费| 欧美精品久久久久| 成人黄片免费| 国产精品日韩无码| 成人69AV| 久久伊人影院| 激情五月天影院| 老太色HD色老太HD| 精品视频第一页| 福利视频三区| 高清无码在线免费观看视频| 韩国无码一区二区| 欧美成人精品三级网站| 人妻18无码人伦一区二区三区精品| 久久九九视频| 夜色精品视频| 成人黄色一级A片| 婷婷丁香五月在线| 亚洲图片中文字幕| 一本到在线观看午夜剧场| 乱码少妇| 91性爱嫩逼视频| 另类老妇性bbwbbwbbw| 亭亭色| 欧美www| 在线观看三级网址| 伊人色爱| 北条麻妃精品视频| 乱伦乱伦乱伦中文字幕| 国产香蕉AV| 动漫av网站| 羞羞av| 日韩不卡一区二区三区| 囯产精品一区二区三区AV做线| 影音先锋av成人电影| 色国产在线视频| 91蜜桃传媒在线观看| 大香蕉这里只有精品| 性生活无码| 精品少妇一区| 俺也去也| 怡红院男人的天堂| 激情一区二区三区| 狠狠地操| 无码人妻日韩精品一区二区三| 日韩精品一区二区三区四在线播放 | 三级成人av| 在线观看中文字幕网站| 超碰操一操| 成人午夜精品无码区| 中文字幕丰满熟妇人妻| 亚洲字幕无码| 99免费精品视频| 日日精品| 中文字幕观看av| 可以看的三级网站| 操久在线| 成人免费看A片| 亚洲成人无码在线播放| 日本親子亂子倫XXXX50路| 亚洲人妻少妇| 黄色电影免费在线观看| 影音先锋三级片| 久热大香蕉| 欧美色乱| 伊人免费视频在线观看| 少妇搡BBBB搡BBB搡毛片少妇| 超碰人妻97| 一本色道久久综合无码| 69欧美视频| 国产乱子伦一区二区三区在线观看 | 日韩强操逼网| 99热精品久久| 草逼123| 久久精品一区二区三区不卡牛牛| 老太色HD色老太HD| 91精品综合| 91免费看| 无码乱伦| 一级黄色影院| 日韩在线网址| 中文电视剧字幕在线播放免费视频| 一级片免费视频| 强伦轩一区二区三区四区播放方式| 人妻无码中文久久久久专区| 麻豆视频在线播放| 97国产成人| 黄色视频网站在线免费观看| 免费看一级无码成人片| 欧美日本激情| 91人妻人人澡人人爽人人DVD| 精品视频网| 成人网站av| 黄色成人视频在线观看| 欧美色图狠狠操| 日韩一区二区三区免费视频| 久久涩| 国产黄片免费观看| 苍井空无码一区二区三区| 中文字幕在线视频日本| 亚洲国产精品二二三三区| 一区二区高清视频| 国产成人AV免费观看| 国产精品色情A级毛片| 国产日韩一区二区三区| 日韩av一区二区三区| 视频一视频二在线视频| 国产精品中文字幕在线观看| 国产成人视频免费| 波多野结衣无码视频在线观看| 蜜桃网一区二区| AV天堂中文字幕| 黄片网站在线看| 大香蕉国产在线| 日韩二级片| 国产成人精品麻豆| 久久99深爱久久99精品| 天天色天天干天天| 色噜噜一区二区三区| AV无码网站| 中文字幕一区三区三A片密月| 好逼123| 欧美3p视频| 成人在线中文字幕| 精品人妻系列| 国产成人免费在线视频| 亚洲小视频在线观看| 伊人丁香| 亚久久久| 亚洲欧洲免费视频| 能看的操逼网站| 青青在线免费视频| 天天天操| 日韩AV成人无码久久电影| 黄色无遮挡| www.俺去也| 人妻免费在线视频| 老婆中文字幕乱码中文乱码| 亚洲中文在线观看| 翔田千里一区二区三区精品播放| 中文字幕免费在线播放| 成人精东影业JDAV3密友| 在线视频福利导航| 91探花视频精选在线播放| 99精品偷自拍| 日本色婷婷| 黄色视频网站免费观看| 91蝌蚪在线视频| 国产精品tv| 日韩免费在线视频观看| 99热综合在线| 一级A片免费观看| 国产在线观看mv免费全集电视剧大全| 三个黑人猛躁我一晚上| 超碰91在线| 永久免费AV| 欧美黑吊大战白妞| 视频一区在线播放| 亚洲免费观看高清完整版在线| 91视频免费观看| 成功精品影院| 怡红院AV| 国产天堂在线观看| 小處女末发育嫩苞AV| 欧美黄片无码| 男女做爱视频网站| www五月天com| 蜜桃精品视频在线观看| 久久不卡| 激情国产精品| 91看片| 91青青草| 婷婷亚洲精品| 中文字幕国产视频| 熟妇高潮一区二区高潮| 午夜乱论| 成人视频123| 激情操逼视频| 特级无码| 亚洲国产成人精品女人久久| 精品1区| 日本成人午夜福利| 97天天操| 国产又粗又长的视频| 色哟哟一区| 国产精品无码专区| 2017天天干天天射| 国产精品美女毛片真酒店| 动漫人物插画动漫人物的视频软件| 精品蜜桃秘一区二区三区在线播放 | 在线观看禁无码精品| 色臀av| 夜色88V精品国产亚洲| 人人色人人摸| 无码AV网| 日韩一级黄片| 欧美一级婬片AAAAAA片| 成人小视频十八禁免费观看| 欧美性受XXXX黑人XYX性爽冫| 天天爽夜夜爽精品成人免费| 蜜桃网站在线观看| 91久久精品国产91久久公交车| 97精品在线视频| 大香蕉综合伊人| 九九热精品视频在线观看| 九九r在线精品观看视频| 亚洲无码在线播放视频| 淫荡五月天视频导航| 玖玖爱在线精品视频| 成人免费视频在线观看| 欧美三级一级| 欧美日韩精品久久久免费观看| 国产精品久久久久久久久借妻| 激情六月天| 成人亚洲欧美| 伊人成人视频在线观看| 中文有码在线| 日韩AⅤ无码一区二区三区| 日日夜夜精品视频| 五月婷视频| 黄频美女日本免费| 日本不卡在线视频| 欧美一区二区三区系列电影| 亚洲综合小说| 3D精品啪啪一区二区三区| 一区日韩| 九久久| 人人做人人爱人人做人人乐的意思| 成人网站在线看。| 日韩无码网站| 国产高潮又爽又无遮挡又免费| 成人免费视频在线观看| 我要操网站| 操逼视频看看| 日日撸| 国产久久精品| 亚洲Av无码午夜国产精品色软件 | 久久美女视频| 在线观看国产小视频| 粉嫩一区二区三区四区| 国产一級A片免费看| 日韩肏屄视频在线观看| 成人精品毛片| 国产伦精品一区二区三区妓女下载 | 成人毛片18女人毛片| www.91AV| 国产一级A片在线观看| 无码人妻一区二区三区| 欧美三级推荐| 成人免费无码激情AV片| 九九热只有精品| 欧美在线黄片| 在线观看日韩精品| 日本三级网址| 老司机无码视频| 夜夜av| 天堂a√中文8| 手机在线观看av| 人人摸人人操人人爱| av高清无码| 天堂资源中文在线| 91AV天天在线观看| 超碰97久久| 国产一级a一片成人AV| 久了中文字幕| 一区二区三区免费观看| 欧美精品成人免码在线| 国产激情视频网站| 亚洲第一综合网| 国产精品免费在线| 91好爽| 一级a看片在线观看| 中文字幕无码精品三级在线欧美| 午夜操| 欧美日韩高清无码| 69式荫蒂被添全过程| 久久天天| 色婷婷在线视频观看| 性爱91视频| 干日本少妇| 三级在线视频| 天天干天天色| 日本三级AAA三级AAAA97 | 免费一级做a爱片毛片A片小说 | 国产精品码ls字幕影视| 亚洲人做受| 亚洲精品综合| 青青草无码| 欧美性受XXXX黑人XYX性爽冫| 亚洲黄色Av| 狠狠操夜夜操| 一区性爱| 最近中文字幕免费MV第一季歌词十| 91丨九色丨老熟女探花| 大香伊人国产| 蜜桃视频在线观看18| 欧美性爱一区二区三区| 国产TS在线| 福利在线看| 天天做天天爱| 国产黄色视频免费在线观看| 日韩三级麻豆| 亚洲国产精品久久久久婷婷老年 | 91在线网址| 国产成人av在线观看| а√天堂中文官网8| 国产嫩草久久久一二三久久免费观看| 麻豆91精品人妻成人无码| 91狠狠综| 久久成人无码电影| 国产成人V在线精品一区| 性爱免费专区| 日韩高清无码一区二区| 色色影音先锋| 亚洲欧美在线视频免费| 97精品人妻麻豆一区二区| 69精品| 日韩黄页网站| a视频免费观看| 伊人影院久久| 日韩三级在线播放| 国产女人水真多18毛片18精品 | 性爱视频免费| 久久午夜无码鲁丝| 中文无码影院| www.seses| 久久人搡人人玩人妻精AV香蕉| 91久久欧美极品XXXXⅩ| 国产高清一区二区| 日韩家庭乱伦| 免费A在线观看| 欧美亚洲成人在线观看| 在线观看免费a片| 欧美操操操| 人成视频在线观看| 日韩免费A片| 亚州在线视频| 人妻天天干| 91小视频在线| 日韩三级片在线视频| 伊人大香蕉视频在线观看| 五月天久久久久久久| 最新日韩中文字幕| 欧美精品无码一区二区| 国产狂喷水潮免费网站www| 一区二区三区无码视频| 蜜臀久久99精品久久久老牛影视 | 加勒比无码人妻| 欧美色五月| 伊人999| 大荫蒂hd大荫蒂视频| 综合色婷婷一区二区亚洲欧美国产 | 手机在线看片av| 俺去了无码| 成人网一区二区| 欧美性视频网站| 五月婷婷俺來也| 日本东京热视频| 免费黄色电影在线观看| 国产毛片在线| 中文字幕视频| 超碰久草| 五月天婷婷丁香| 日韩视频免费观看| 无码视频免费在线观看| 国产熟妇婬乱一区二区| 神马午夜51| av无码高清| 麻豆AV96熟妇人妻| 婷婷国产亚洲精品网站| 欧美黄色一级视频| 成人无码三级| 欧美AAAAAA视频| 欧美激情四射老司机| 大香蕉av一区二区三区在线观看 | 国产午夜在线观看| 69人妻人人澡人人爽人人精品| Av大香蕉| 人人摸人人艹| 大鸡巴在线| www黄片| 99久热| 欧美一区二区三区激情| 新狠狠干| 亚洲国产精品自| 国产精品啪啪啪啪| 吃奶做爱视频| 乱伦婷婷| 狠狠干综合网| 久草手机视频在线观看| A视频免费观看| 日本一区二区视频| 人妻无码一区二区三区摄像头| 欧美人与禽乱婬A片| 黄色片在线看| 亚洲天堂在线视频| 2012天天夜夜| 中文字幕97| 蜜臀久久99久久久久久宅男| 亚洲国产欧美在线| 激情爱爱网站| 国产视频一区二区在线观看| 午夜蜜桃人妻一区二区| 国产女人视频| 嫩草视频| 丝袜内射| 粉嫩小泬BBBB免费看| 免费福利视频网站| 婷婷国产成人精品视频| 久久精品视频网站| 操逼在线播放| 在线中文字幕av| 国产精品福利在线观看| 在线观看av中文字幕| www.av在线播放| 亚洲精品自拍偷拍| 91.www91成人影视在线观看91成人网址9 | 人操人人人操| 午夜在线无码| 中文字幕亚洲无码视频| 蜜臀av一区二区| 欧美强开小嫩苞| 国产精品123区| 一本久久A精品一合区久久久| 日本黄色大片网站| 西西4444大胆无码视频| 国产又大又黄| 免费看A| 乳揉みま痴汉电车羽月希免费观看| 鸡巴在线观看| 久久伊人电影| 国产秘精品一区二区三区免费| 成人毛片| 18禁黄网站| 翔田千里无码视频| 中文字幕免费无码| 粉嫩小泬BBBB免费看-百度| 亚洲天堂2017| 久久丁香五月婷婷五月天激情视频| 91网在线观看| 青青草原成人在线视频| 成人性爱免费视频| 久草成人| 国产婷婷内射| 性爱小说视频| 国产二区三区| 操逼日爱| 熟女人妻在线视频| 美女大香蕉| 青青草视频在线免费观看| 欧美精品午夜福利无码| 3D动漫操逼视频| 欧美精品日韩| 18禁在线播放| 日韩AV电影网| 国产三级免费观看| 99成人国产精品视频| 懂色av粉嫩AV蜜臀AV| 4388亚洲最大| 国产精品一级a毛一级a| 亚洲无码电影网| 亚洲AV无码成人精品区东京热 | 亚洲福利网站| 国产在线观看免费视频今夜| 亚洲日本中文字幕在线观看 | 三级片欧美| 黄色片视频日本| 国产探花在线观看| 操屄视频在线观看| 成人做爰100部片视频| 爱就色色网| 性爱二区| AV三级无码| 国产黄片一区二区| 欧美日韩无码| 簧片在线免费观看| 伊人干综合| 久久五月亭亭| 午夜精品一区二区三区在线视频| 黑人丰满大荫蒂| 日本无码电影| 99视频网| 东方成人AV| 尤物av| 91在线无码精品秘国产三年| 一区在线视频| 苗条一区小视频| 人妻被午夜福利AV| 曰本精品综合网在线| 999精品视频在线| 日韩一a| 西西444WWW无码视频软件| 91精品国产综合久久久蜜臀图片| 欧美日韩视频免费观看| 免费A片在线| 欧美日韩肏屄视频| 五月天天| 婷婷五月天影视| 在线色网站| 尤物精品在线| 91人妻最真实刺激绿帽| 亚洲无码AV在线播放| 91精品国产偷窥一区二区| 91成人福利| 久久久久久亚洲Av无码精品专口| 蜜柚AV| 欧美日韩视频在线| 日韩人妻无码一区二区三区中文| 国产精品久久久一区二区三区| 人妻少妇中文字幕久久牛牛| 综合久久久久| 四虎亚洲| 亚洲精品自拍偷拍| 自拍视频国产| 黄片51| 久草大| 九色PORNY9l原创自拍| 免费日逼视频| 免费在线观看黄色视频| 甘肃WBBBB搡wBBBB| 天堂成人在线视频| 中国少妇xxx| 大香蕉青青| 中国一级片| 久久精品秘一区二区三免费| 在线观看亚洲专区| 少妇高潮无码| a网站在线观看| 无码成人片| 国产中文字幕在线观看| 天天色伊人| 亚洲色成人网站www永久四虎| 水多多成人视频| 在线亚洲欧洲| 精品人妻一区二区三区在线视频不卡 | 欧美激情网址| 91女人18毛片水多国产| 中文字幕观看av| 99在线精品视频在线观看| 精品久久久久久亚洲| 亚洲AV成人一区二区三区不卡 | 婷婷在线综合| 日韩欧美中文字幕在线观看| 久久精品网| 求毛片网址| re久久| 337P粉嫩大胆噜噜噜55569| 9l视频自拍蝌蚪9l成人| AV色色| 日韩综合精品中文字幕66| 日韩操比| 天堂亚洲精品| 国产一级A片免费播放| 首屈一指视频在线观看| 91大香蕉视频| 北岛玲在线视频| 欧美三级视频在线观看| 搡BBB搡BBBB搡BBBB| 国产精品久久久久国产A级 | 91人妻人人澡人人爽精品| 91人妻人人澡人人爽人人精 | 日本内射网站| 久久草在线观看| 国产成人一区二区三区A片免费| 亚洲性爱综合| 无码逼逼| 人妻天天操| 无码狠狠躁久久久久久久91| 内射免费看| 欧洲天堂在线视频网站| 免费无码一区二区三区四区五区| 亚洲婷婷AV| 九九性爱网| 亚洲无码一本道| 欧美黄色影院| 亚洲成人性爱av| 成人才看的在线视频| 竹菊传媒一区二区三区| 在线内射视频| 黄色AV天堂| 无码在线免费观看| 久热热| 欧美性猛交ⅩXXX乱大交| 亚洲综合中文字幕在线| 爆乳尤物一区二区三区| 884aa四虎影成人精品一区| 无码成人视频| 黄片观看| 乌克兰性爱视频| 中文字幕视频在线播放| 一夲道无码专区av无码A片| 国产色婷婷一区二区| 肏屄综合网| 西西人体44www大胆无码| JiZZjiZZ亚洲成熟熟妇| 99国产在线视频| 天天精品无码| 欧美成人精品激情在线观看| R四虎18| 日韩成人小电影| 亚洲成人中文字幕| 国产搡BBB爽爽爽视频| 丁香五月婷婷基地| 18AV在线观看| 人人操人人摸人人| 亚洲综合社区在线| 一级婬片A片AAAAA毛片| 久久免费视频6| 在线观看视频黄| 91视频亚洲| 免费观看成人片| 国产亚洲成人综合| 中文字幕777| 黄色在线观看免费| 91美女在线观看| 蜜臀AV午夜精品| 亚洲无码成人片| 黄色精品| 安徽妇搡BBBB搡BBB| 狠狠成人| 中文无码一区| 天堂a√中文8| 人人操天天| 亚洲AV无码专区在线播放中文 | 国产网站视频| 国产小视频在线播放| 99热99| 欧美东京热视频| 日韩精品小电影| 国产色色色色| 中文字幕视频在线观看| 强开小嫩苞毛片一二三区| 日韩精品成人免费观看视频 | 黄色激情在线| 天堂中文在线观看| 久草a视频| 午夜性爱视频| 成人午夜无码视频| 欧美日韩群交| 亚洲一二三四区| 久久久WWW成人免费精品| 夜夜操夜夜爽| 99热精品久久| 青娱乐免费视频| 国产乱伦自拍| 欧美一级片内射| 午夜试看120秒体验区的特点| 日韩AV中文| 国产无遮挡又黄又爽又色学生软件| 91亚洲在线观看| 久久午夜无码鲁丝片主演是谁| 91av视频在线| 亚洲AV无码第一区二区三区蜜桃| 国产av小电影| 羞羞视频com.入口| 91成人在线观看国产| 亚洲视频偷拍| 欧美午夜成人一区二区三区 | 色老板在线观看视频| 九九性爱视频| 欧美美女视频网站| 青青草娱乐视频| 免费视频二区| 91视频美女模特| 加勒比一区二区三区| 啪啪毛片| 国产精品无毛五区六区| 免费观看亚洲视频| 18禁一区| 曰本中文字幕在线视频| 黄色视频在线观看地址| 男女www视频| 亚洲AV在线人妻| 先锋影音AV资源站| 91亚洲欧美| 丰满人妻一区二区三区视频在线不卡| 国产精品一区二区免费| 美女91视频网站| 阿宾MD0165麻豆沈娜娜| 亚洲熟妇AV日韩熟妇在线| 中文无码日韩欧美久久| 男人天堂手机视频| 黑人亚洲娇小videos∞| 天堂在线中文| 操极品美女| 亚洲青青| 操大香蕉| 天堂网中文在线| 日韩无码精品一区二区三区| 中文一级片| 亚洲综合免费观看高清完整版在线观| 毛片操逼视频| 天天做天天干| 国产中文字字幕乱码无限| 臭小子晚上让你爽个够视频| 国产欧美精品成人在线观看| 日韩久久精品视频| 色色五月天婷婷| 黄色录像一级带| 日韩中文无码字幕| 丁香五月在线视频| 亚洲图片在线| 久久综合伊人| 久久久3| 色色色色综合|