精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

用Redis實現延遲隊列,我研究了兩種方案,發現并不簡單

開發 前端
雖然基于MQ這個方式走不通了,但是這個項目中使用到Redis,所以我就想是否能夠使用Redis來代替MQ實現延遲隊列的功能,于是我就查了一下有沒有現成可用的方案,別說,還真給我查到了兩種方案,并且我還仔細研究對比了這兩個方案,發現要想很好的實現延遲隊列,并不簡單。

?背景

前段時間有個小項目需要使用延遲任務,談到延遲任務,我腦子第一時間一閃而過的就是使用消息隊列來做,比如RabbitMQ的死信隊列又或者RocketMQ的延遲隊列,但是奈何這是一個小項目,并沒有引入MQ,我也不太想因為一個延遲任務就引入MQ,增加系統復雜度,所以這個方案直接就被pass了。

雖然基于MQ這個方式走不通了,但是這個項目中使用到Redis,所以我就想是否能夠使用Redis來代替MQ實現延遲隊列的功能,于是我就查了一下有沒有現成可用的方案,別說,還真給我查到了兩種方案,并且我還仔細研究對比了這兩個方案,發現要想很好的實現延遲隊列,并不簡單。

監聽過期key

基于監聽過期key的方式來實現延遲隊列是我查到的第一個方案,為了弄懂這個方案實現的細節,我還特地去扒了扒官網,還真有所收獲

1、Redis發布訂閱模式

一談到發布訂閱模式,其實一想到的就是MQ,只不過Redis也實現了一套,并且跟MQ賊像,如圖:

圖片

圖中的channel的概念跟MQ中的topic的概念差不多,你可以把channel理解成MQ中的topic。

生產者在消息發送時需要到指定發送到哪個channel上,消費者訂閱這個channel就能獲取到消息。

2、keyspace notifications

在Redis中,有很多默認的channel,只不過向這些channel發送消息的生產者不是我們寫的代碼,而是Redis本身。當消費者監聽這些channel時,就可以感知到Redis中數據的變化。

這個功能Redis官方稱為keyspace notifications,字面意思就是鍵空間通知。

這些默認的channel被分為兩類:

  • 以__keyspace@<db>__:為前綴,后面跟的是key的名稱,表示監聽跟這個key有關的事件。舉個例子,現在有個消費者監聽了__keyspace@0__:sanyou這個channel,sanyou就是Redis中的一個普通key,那么當sanyou這個key被刪除或者發生了其它事件,那么消費者就會收到sanyou這個key刪除或者其它事件的消息
  • 以__keyevent@<db>__:為前綴,后面跟的是消息事件類型,表示監聽某個事件同樣舉個例子,現在有個消費者監聽了__keyevent@0__:expired這個channel,代表了監聽key的過期事件。那么當某個Redis的key過期了(expired),那么消費者就能收到這個key過期的消息。如果把expired換成del,那么監聽的就是刪除事件。具體支持哪些事件,可從官網查。

上述db是指具體的數據庫,Redis不是默認分為16個庫么,序號從0-15,所以db就是0到15的數字,示例中的0就是指0對應的數據庫。

圖片

3、延遲隊列實現原理

通過對上面的兩個概念了解之后,應該就對監聽過期key的實現原理一目了然了,其實就是當這個key過期之后,Redis會發布一個key過期的事件到__keyevent@<db>__:expired這個channel,只要我們的服務監聽這個channel,那么就能知道過期的Key,從而就算實現了延遲隊列功能。

所以這種方式實現延遲隊列就只需要兩步:

  • 發送延遲任務,key是延遲消息本身,過期時間就是延遲時間
  • 監聽__keyevent@<db>__:expired這個channel,處理延遲任務

4、demo

好了,基本概念和核心原理都說完了之后,又到了show me the code環節。

好巧不巧,Spring已經實現了監聽__keyevent@*__:expired?這個channel這個功能,__keyevent@*__:expired?中的*代表通配符的意思,監聽所有的數據庫。

所以demo寫起來就很簡單了,只需3步即可

引入pom

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>

配置類

@Configuration
public class RedisConfiguration {

@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(connectionFactory);
return redisMessageListenerContainer;
}

@Bean
public KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer redisMessageListenerContainer) {
return new KeyExpirationEventMessageListener(redisMessageListenerContainer);
}

}

KeyExpirationEventMessageListener實現了對__keyevent@*__:expiredchannel的監聽

圖片

當KeyExpirationEventMessageListener收到Redis發布的過期Key的消息的時候,會發布RedisKeyExpiredEvent事件

圖片

所以我們只需要監聽RedisKeyExpiredEvent事件就可以拿到過期消息的Key,也就是延遲消息。

對RedisKeyExpiredEvent事件的監聽實現MyRedisKeyExpiredEventListener

@Component
public class MyRedisKeyExpiredEventListener implements ApplicationListener<RedisKeyExpiredEvent> {

@Override
public void onApplicationEvent(RedisKeyExpiredEvent event) {
byte[] body = event.getSource();
System.out.println("獲取到延遲消息:" + new String(body));
}

}

整個工程目錄也簡單

圖片

代碼寫好,啟動應用

之后我直接通過Redis命令設置消息,就沒通過代碼發送消息了,消息的key為sanyou,值為task,值不重要,過期時間為5s

set sanyou task 

expire sanyou 5

如果上面都理論都正確,不出意外的話,5s后MyRedisKeyExpiredEventListener應該可以監聽到sanyou這個key過期的消息,也就相當于拿到了延遲任務,控制臺會打印出獲取到延遲消息:sanyou。

于是我滿懷希望,靜靜地等待了5s。。

5、4、3、2、1,時間一到,我查看控制臺,但是控制臺并沒有按照預期打印出上面那句話。

為什么會沒打印出?難道是代碼寫錯了?正當我準備檢查代碼的時候,官網的一段話道出了真實原因。

圖片

我給大家翻譯一下上面這段話講的內容。

上面這段話主要討論的是key過期事件的時效性問題,首先提到了Redis過期key的兩種清除策略,就是面試八股文常背的兩種:

  • 惰性清除。當這個key過期之后,訪問時,這個Key才會被清除
  • 定時清除。后臺會定期檢查一部分key,如果有key過期了,就會被清除

再后面那段話是核心,意思是說,key的過期事件發布時機并不是當這個key的過期時間到了之后就發布,而是這個key在Redis中被清理之后,也就是真正被刪除之后才會發布。

到這我終于明白了,上面的例子中即使我設置了5s的過期時間,但是當5s過去之后,只要兩種清除策略都不滿足,沒人訪問sanyou這個key,后臺的定時清理的任務也沒掃描到sanyou這個key,那么就不會發布key過期的事件,自然而然也就監聽不到了。

至于后臺的定時清理的任務什么時候能掃到,這個沒有固定時間,可能一到過期時間就被掃到,也可能等一定時間才會被掃到,這就可能會造成了客戶端從發布到監聽到的消息時間差會大于等于過期時間,從而造成一定時間消息的延遲,這就著實有點坑了。。

5、坑

除了上面測試demo的時候遇到的坑之外,在我深入研究之后,還發現了一些更離譜的坑。

丟消息太頻繁

Redis的丟消息跟MQ不一樣,因為MQ都會有消息的持久化機制,可能只有當機器宕機了,才會丟點消息,但是Redis丟消息就很離譜,比如說你的服務在重啟的時候就消息會丟消息。

Redis實現的發布訂閱模式,消息是沒有持久化機制,當消息發布到某個channel之后,如果沒有客戶端訂閱這個channel,那么這個消息就丟了,并不會像MQ一樣進行持久化,等有消費者訂閱的時候再給消費者消費。

所以說,假設服務重啟期間,某個生產者或者是Redis本身發布了一條消息到某個channel,由于服務重啟,沒有監聽這個channel,那么這個消息自然就丟了。

消息消費只有廣播模式

Redis的發布訂閱模式消息消費只有廣播模式一種。

所謂的廣播模式就是多個消費者訂閱同一個channel,那么每個消費者都能消費到發布到這個channel的所有消息。

圖片

如圖,生產者發布了一條消息,內容為sanyou,那么兩個消費者都可以同時收到sanyou這條消息。

所以,如果通過監聽channel來獲取延遲任務,那么一旦服務實例有多個的話,還得保證消息不能重復處理,額外地增加了代碼開發量。

接收到所有key的某個事件

這個不屬于Redis發布訂閱模式的問題,而是Redis本身事件通知的問題。

當消費者監聽了以__keyevent@<db>__:開頭的消息,那么會導致所有的key發生了事件都會被通知給消費者。

舉個例子,某個消費者監聽了__keyevent@*__:expired這個channel,那么只要key過期了,不管這個key是張三還會李四,消費者都能收到。

所以如果你只想消費某一類消息的key,那么還得自行加一些標記,比如消息的key加個前綴,消費的時候判斷一下帶前綴的key就是需要消費的任務。

所以,綜上能夠得出一個非常重要的結論,那就是監聽Redis過期Key這種方式實現延遲隊列,不穩定,坑賊多!

那有沒有比較靠譜的延遲隊列的實現方案呢?這就不得不提到我研究的第二種方案了。

Redisson實現延遲隊列

Redisson他是Redis的兒子(Redis son),基于Redis實現了非常多的功能,其中最常使用的就是Redis分布式鎖的實現,但是除了實現Redis分布式鎖之外,它還實現了延遲隊列的功能。

先來個demo,后面再來說說這種實現的原理。

1、demo

引入pom

<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.1</version>
</dependency>

封裝了一個RedissonDelayQueue類

@Component
@Slf4j
public class RedissonDelayQueue {

private RedissonClient redissonClient;

private RDelayedQueue<String> delayQueue;
private RBlockingQueue<String> blockingQueue;

@PostConstruct
public void init() {
initDelayQueue();
startDelayQueueConsumer();
}

private void initDelayQueue() {
Config config = new Config();
SingleServerConfig serverConfig = config.useSingleServer();
serverConfig.setAddress("redis://localhost:6379");
redissonClient = Redisson.create(config);

blockingQueue = redissonClient.getBlockingQueue("SANYOU");
delayQueue = redissonClient.getDelayedQueue(blockingQueue);
}

private void startDelayQueueConsumer() {
new Thread(() -> {
while (true) {
try {
String task = blockingQueue.take();
log.info("接收到延遲任務:{}", task);
} catch (Exception e) {
e.printStackTrace();
}
}
}, "SANYOU-Consumer").start();
}

public void offerTask(String task, long seconds) {
log.info("添加延遲任務:{} 延遲時間:{}s", task, seconds);
delayQueue.offer(task, seconds, TimeUnit.SECONDS);
}

}

這個類在創建的時候會去初始化延遲隊列,創建一個RedissonClient對象,之后通過RedissonClient對象獲取到RDelayedQueue和RBlockingQueue對象,傳入的隊列名字叫SANYOU,這個名字無所謂。

當延遲隊列創建之后,會開啟一個延遲任務的消費線程,這個線程會一直從RBlockingQueue中通過take方法阻塞獲取延遲任務。

添加任務的時候是通過RDelayedQueue的offer方法添加的。

controller類,通過接口添加任務,延遲時間為5s

@RestController
public class RedissonDelayQueueController {

@Resource
private RedissonDelayQueue redissonDelayQueue;

@GetMapping("/add")
public void addTask(@RequestParam("task") String task) {
redissonDelayQueue.offerTask(task, 5);
}

}

啟動項目,在瀏覽器輸入如下連接,添加任務

http://localhost:8080/add?task=sanyou

靜靜等待5s,成功獲取到任務。

圖片

2、實現原理

如下圖就是上面demo中,一個延遲隊列會在Redis內部使用到的channel和數據類型

圖片

SANYOU前面的前綴都是固定的,Redisson創建的時候會拼上前綴。

  • redisson_delay_queue_timeout:SANYOU,sorted set數據類型,存放所有延遲任務,按照延遲任務的到期時間戳(提交任務時的時間戳 + 延遲時間)來排序的,所以列表的最前面的第一個元素就是整個延遲隊列中最早要被執行的任務,這個概念很重要
  • redisson_delay_queue:SANYOU,list數據類型,也是存放所有的任務,但是研究下來發現好像沒什么用。。
  • SANYOU,list數據類型,被稱為目標隊列,這個里面存放的任務都是已經到了延遲時間的,可以被消費者獲取的任務,所以上面demo中的RBlockingQueue的take方法是從這個目標隊列中獲取到任務的
  • redisson_delay_queue_channel:SANYOU,是一個channel,用來通知客戶端開啟一個延遲任務

有了這些概念之后,再來看看整體的運行原理圖

圖片

  • 生產者在提交任務的時候將任務放到redisson_delay_queue_timeout:SANYOU中,分數就是提交任務的時間戳+延遲時間,就是延遲任務的到期時間戳
  • 客戶端會有一個延遲任務,為了區分,后面我都說是客戶端延遲任務。這個延遲任務會向Redis Server發送一段lua腳本,Redis執行lua腳本中的命令,并且是原子性的

圖片

這段lua腳本主要干了兩件事:

  • 將到了延遲時間的任務從redisson_delay_queue_timeout:SANYOU中移除,存到SANYOU這個目標隊列
  • 獲取到redisson_delay_queue_timeout:SANYOU中目前最早到過期時間的延遲任務的到期時間戳,然后發布到redisson_delay_queue_channel:SANYOU這個channel中

當客戶端監聽到redisson_delay_queue_channel:SANYOU?這個channel的消息時,會再次提交一個客戶端延遲任務,延遲時間就是消息(最早到過期時間的延遲任務的到期時間戳)- 當前時間戳,這個時間其實也就是redisson_delay_queue_channel:SANYOU中最早到過期時間的任務還剩余的延遲時間。

此處可以等待10s,好好想想。。

這樣,一旦時間來到了上面說的最早到過期時間任務的到期時間戳,redisson_delay_queue_timeout:SANYOU?中上面說的最早到過期時間的任務已經到期了,客戶端的延遲任務也同時到期,于是開始執行lua腳本操作,及時將到了延遲時間的任務放到目標隊列中。然后再次發布剩余的延遲任務中最早到期的任務到期時間戳到channe中,如此循環往復,一直運行下去,保證redisson_delay_queue_timeout:SANYOU中到期的數據能及時放到目標隊列中。

所以,上述說了一大堆的主要的作用就是保證到了延遲時間的任務能夠及時被放到目標隊列。

這里再補充兩個特殊情況,圖中沒有畫出:

第一個就是如果redisson_delay_queue_timeout:SANYOU是新添加的任務(隊列之前有或者沒有任務)是隊列中最早需要被執行的,也會發布消息到channel,之后就按時上面說的流程走了。

添加任務代碼如下,也是通過lua腳本來的

圖片

第二種特殊情況就是項目啟動的時候會執行一次客戶端延遲任務。項目在重啟時,由于沒有客戶端延遲任務的執行,可能會出現redisson_delay_queue_timeout:SANYOU隊列中有到期但是沒有被放到目標隊列的可能,重啟就執行一次就是為了保證到期的數據能被及時放到目標隊列中。

3、與第一種方案比較

現在來比較一下第一種方案和Redisson的這種方案,看看有沒有第一種方案的那些坑。

第一個任務延遲的問題,Redisson方案理論上是沒有延遲的,但是當消息數量增加,消費者消費緩慢這個情況下可能會導致延遲任務消費的延遲。

第二個丟消息的問題,Redisson方案很大程度上減輕了丟消息的可能性,因為所有的任務都是存在list和sorted set兩種數據類型中,Redis有持久化機制,就算Redis宕機了,也就可能會丟一點點數據。

第三個廣播消費任務的問題,這個是不會出現的,因為每個客戶端都是從同一個目標隊列中獲取任務的。

第四個問題是Redis內部channel發布事件的問題,跟這種方案不沾邊,就更不可能存在了。

所以,通過上面的對比可以看出,Redisson這種實現方案就顯得更加的靠譜了。

責任編輯:武曉燕 來源: 三友的java日記
相關推薦

2021-12-08 10:47:35

RabbitMQ 實現延遲

2012-06-26 09:40:14

部署開發管理

2024-05-08 14:49:22

Redis延遲隊列業務

2019-05-15 10:59:50

開發者技能工具

2022-02-09 07:03:01

SpringNacos服務注冊

2010-05-28 09:49:48

MySQL遠程連接

2020-09-09 14:49:19

面試官數據結構

2010-05-19 15:53:17

部署統一通信

2010-06-07 17:41:42

Sendmail 配置

2023-09-12 14:58:00

Redis

2023-11-09 08:14:07

時間窗口限流

2009-07-02 15:50:36

JSP體系結構

2018-06-04 09:43:53

分層存儲Linux

2020-07-20 14:10:48

AI 數據人工智能

2011-08-09 13:50:01

iPhone動畫UIView

2018-12-16 16:12:04

區塊鏈數據庫數據集

2010-09-30 14:35:36

JS浮點溢出

2010-03-26 18:41:51

Nginx 502錯誤

2010-03-11 10:38:34

Python運算符

2010-08-20 09:39:43

IE6IE7Firefox
點贊
收藏

51CTO技術棧公眾號

久久一区免费| 日韩中文字幕久久| 国产二区视频在线播放| 深爱激情五月婷婷| 日本中文字幕一区| 欧美成人小视频| 国产精品无码网站| 亚洲欧洲专区| 欧美日韩性生活视频| 亚洲精品国产精品久久| www.97av.com| 日韩高清不卡一区二区| 欧美极度另类性三渗透| 东方伊人免费在线观看| 精品三级av在线导航| 欧美日免费三级在线| 极品美女扒开粉嫩小泬| 嫩草香蕉在线91一二三区| proumb性欧美在线观看| 成人免费淫片视频软件| caoporn国产| 女人色偷偷aa久久天堂| 在线播放国产一区中文字幕剧情欧美| 亚洲热在线视频| 少妇一区视频| 亚洲成人久久影院| 一区二区免费电影| 麻豆导航在线观看| 成人app下载| 亚洲伊人成综合成人网| 日韩一区二区三区四区 | 亚洲成熟女性毛茸茸| 久久久天天操| 久久青草福利网站| h色网站在线观看| 精品一级毛片| 亚洲欧美在线免费观看| 欧美性生交xxxxx| 国产一区二区三区免费观看在线| 在线日韩一区二区| 少妇性饥渴无码a区免费| 在线欧美三级| 亚洲色图欧美激情| 在线视频欧美一区| 91激情在线| 中文字幕免费不卡在线| 青青草久久网络| 午夜福利一区二区三区| 99久久夜色精品国产网站| www.久久草| 成人av免费播放| 国产精品99久久久久久有的能看| 国产免费观看久久黄| 中文字幕视频免费观看| 美女脱光内衣内裤视频久久影院| 国产成人精彩在线视频九色| 男人天堂av在线播放| 亚洲尤物影院| 清纯唯美日韩制服另类| 国产剧情在线视频| 久久精品二区三区| 国产精品免费久久久久影院| 中文字幕在线天堂| 美女在线一区二区| 91免费视频国产| 国产精品丝袜黑色高跟鞋| 国产呦萝稀缺另类资源| 波多野结衣一区二区三区在线观看 | 国产精品成人免费一区久久羞羞| 日韩欧美中文在线观看| 精品久久久久久久一区二区蜜臀| 国产又黄又嫩又滑又白| 国产女主播喷水视频在线观看| h片在线观看网站| 成人欧美一区二区三区小说| 99热这里只有精品7| av在线免费观看网址| 一区二区视频免费在线观看| 成年人看的毛片| 亚洲精品动漫| 欧美日韩日日骚| 亚洲av毛片在线观看| 综合激情网...| 日韩国产精品亚洲а∨天堂免| 亚洲人成人无码网www国产| 精品国产乱码久久久| 色系列之999| 久久久久久久久99| 久久三级福利| 91影视免费在线观看| 六月婷婷综合网| 久久精品网站免费观看| 中文有码久久| 日本在线影院| 欧美精品在线一区二区三区| 国产chinese中国hdxxxx| 国产一区二区三区不卡视频网站| www.xxxx欧美| 国产精品久久久免费视频| 奇米色777欧美一区二区| 成人精品一二区| 免费在线观看一级毛片| 日韩一区欧美一区| 国产亚洲综合视频| 久久av网站| 日韩av在线天堂网| 久久久精品少妇| 久久国产精品久久w女人spa| 国产精品久久电影观看| 日本精品一区二区在线观看| 国产精品久久久久天堂| www.日本在线播放| 国产电影一区二区| 亚洲系列中文字幕| 精品91久久久| 国产成人综合视频| 亚洲欧美日韩另类精品一区二区三区 | 国产精品裸体瑜伽视频| 性开放的欧美大片| 黑人精品xxx一区| 在线观看中文av| av资源久久| 91成品人片a无限观看| 亚洲精品免费一区亚洲精品免费精品一区 | 日本高清视频精品| 亚洲精品无码久久久| 国产精品久久久久久妇女6080| 青青草成人免费在线视频| 亚洲国产91视频| 亚洲香蕉成人av网站在线观看| 国产午夜福利片| 国产精品一区二区在线播放 | 成人做爰www看视频软件| 久久密一区二区三区| 日韩**中文字幕毛片| 色综合视频在线| 亚洲资源在线观看| 国产精品熟女一区二区不卡| 日本a口亚洲| 国产成人久久久精品一区| 午夜小视频免费| 婷婷综合久久一区二区三区| 日本wwwxx| 国模吧视频一区| 爽好久久久欧美精品| 久久国产精品久久久久久久久久| 欧美一级黄视频| 亚洲少妇自拍| www.av一区视频| 日本成人不卡| 日韩欧美另类在线| 久久精品99国产精| 国产成人小视频| 日本国产中文字幕| 99ri日韩精品视频| 97色在线视频| 污污网站在线免费观看| 欧美色另类天堂2015| 免费无码一区二区三区| 男人的天堂亚洲| 日韩久久不卡| 成人国产一区| 久久人人爽人人爽爽久久| 一区二区不卡视频在线观看| 亚洲欧洲国产专区| 四川一级毛毛片| 亚洲精品影院在线观看| 久久久久久久久一区| 欧美羞羞视频| 日韩在线观看成人| 亚洲AV无码一区二区三区性| 亚洲成人中文在线| 我和岳m愉情xxxⅹ视频| 蜜臀精品一区二区三区在线观看 | 激情懂色av一区av二区av| 亚洲色图14p| 青娱乐精品在线视频| 亚洲五月六月| 成人高潮a毛片免费观看网站| 97在线视频免费观看| 国产三级视频在线看| 欧美日韩精品一区二区三区蜜桃 | 欧美无乱码久久久免费午夜一区| 国产又粗又长又黄的视频| 国产成a人无v码亚洲福利| 色综合久久久久无码专区| 欧美三级黄网| 久久久夜夜夜| 亚洲一区二区在| 日本超碰一区二区| 日本一区二区在线播放| 快射视频在线观看| 欧美日韩国产一区二区| 夜夜春很很躁夜夜躁| 国产一区二区在线视频| 少妇无码av无码专区在线观看| 欧美一区二区三区激情视频| 99久久伊人精品影院| 韩国成人在线| 午夜精品在线视频| 在线免费观看黄色av| 亚洲第一视频网| 在线观看不卡的av| 婷婷成人激情在线网| 日韩在线一卡二卡| 久久影院午夜论| 三上悠亚 电影| 日韩成人一级大片| 欧美不卡在线播放| 91精品啪在线观看国产18| 久久亚裔精品欧美| 日韩欧美中文字幕一区二区三区 | 成人国产在线看| 国产精品亚洲片在线播放| αv一区二区三区| 少妇精品视频在线观看| 人人澡人人澡人人看欧美| 亚洲h片在线看| 日韩在线观看精品| 国产高清视频在线观看| 日韩国产精品视频| 噜噜噜久久,亚洲精品国产品| 欧美日韩国产另类不卡| 99久久久无码国产精品免费蜜柚| 亚洲电影在线免费观看| 国产女人18水真多毛片18精品| 国产日韩v精品一区二区| 亚洲久久久久久| 丁香一区二区三区| 古装做爰无遮挡三级聊斋艳谭| 蜜桃av噜噜一区| 日本熟妇人妻中出| 香蕉成人久久| 日韩中文字幕在线免费| 欧美色123| www.日本三级| 欧美日本国产| 国产真实老熟女无套内射| 中出一区二区| 韩国黄色一级大片| 日韩久久久久| 日产精品一线二线三线芒果| 亚洲人成亚洲精品| 免费成人深夜夜行视频| 亚洲婷婷伊人| 欧美日韩高清在线一区| 要久久爱电视剧全集完整观看| 国产日韩在线一区二区三区| 99久久香蕉| 国产一区二区免费电影| 伦理一区二区三区| 精品伦理一区二区三区| 牛牛精品成人免费视频| 国产精品久久久久久久久婷婷 | 九九99玖玖| 欧美黑人巨大videos精品| 久久国产精品精品国产色婷婷 | 国产精品美女在线播放| 国产精品99一区二区三区| 国产av不卡一区二区| 91成人国产| 日韩欧美猛交xxxxx无码| 激情久久久久久| 久久亚洲中文字幕无码| 性xx色xx综合久久久xx| 美女喷白浆视频| 久久丁香综合五月国产三级网站 | 精人妻无码一区二区三区| 在线一区二区视频| 91资源在线视频| 精品欧美一区二区三区精品久久 | 欧美一区二区三区久久久| 欧美在线看片a免费观看| 怡春院在线视频| 日韩女同互慰一区二区| 欧美一级在线免费观看| 亚洲欧洲日产国码av系列天堂| av电影在线观看一区二区三区| 久久综合亚洲社区| а√天堂中文资源在线bt| 国产91精品在线播放| 亚洲精品成a人ⅴ香蕉片| 99久久免费国| 国产精品亚洲人成在99www| 熟女熟妇伦久久影院毛片一区二区| 欧美三级第一页| 久久国产乱子伦免费精品| 麻豆91在线看| 久久性爱视频网站| 欧美激情一区在线| 国产真实的和子乱拍在线观看| 一本色道久久加勒比精品| 91丨九色丨丰满| 亚洲国产精品福利| 亚洲搞黄视频| 高清视频欧美一级| 青青青国产精品| 精品在线视频一区二区| 欧美hentaied在线观看| 97超碰青青草| 国产精品亚洲午夜一区二区三区 | 午夜久久久久久电影| 中文字幕在线观看第二页| 亚洲国产精品大全| 久cao在线| 国产97色在线|日韩| 亚洲精品高潮| 夜夜爽99久久国产综合精品女不卡| 精品白丝av| 天堂av手机在线| 国产夜色精品一区二区av| www.99re7.com| 欧美久久久久久久久中文字幕| 欧美女优在线观看| 国模私拍视频一区| 欧美电影在线观看一区| 午夜精品福利一区二区| 国产日韩综合| 免费在线观看日韩av| 亚洲素人一区二区| 国产成人a v| 亚洲毛片在线免费观看| 国产区美女在线| 亚洲www在线| 久久美女精品| 亚洲色图 在线视频| 久久亚洲综合av| 久草手机在线观看| 亚洲第一国产精品| 欧美理论片在线播放| 69堂成人精品视频免费| 国产大片一区| 美女在线视频一区二区| 国产午夜精品久久| 91视频在线视频| 国产亚洲精品美女久久久| 另类激情视频| 欧美一区二区综合| 男人的天堂亚洲在线| 亚洲专区区免费| 欧美性猛交xxxx| 欧美一区二区少妇| 欧美在线免费观看| 免费看av成人| 国产精品亚洲αv天堂无码| www日韩大片| 久久久久久在线观看| 亚洲人成77777在线观看网| 亚洲黄色中文字幕| 日韩免费毛片| 全部av―极品视觉盛宴亚洲| 欧美大波大乳巨大乳| 欧美午夜片在线观看| 成人动漫在线播放| 成人h视频在线| 91不卡在线观看| 欧美激情 亚洲| 岛国av一区二区三区| 欧美中文在线| 国产精品美女av| 1024精品久久久久久久久| 日本一二三区在线| 亚洲国产va精品久久久不卡综合| 色哟哟国产精品色哟哟| 热久久这里只有精品| 日产精品一区二区| 日本黄色一级网站| 亚洲宅男天堂在线观看无病毒| 少妇高潮一区二区三区99小说| 51视频国产精品一区二区| 国产亚洲电影| 樱花草www在线| 亚洲一卡二卡三卡四卡无卡久久| 天堂а√在线8种子蜜桃视频| 668精品在线视频| 超碰成人久久| 久久久久久国产精品日本| 欧美日韩美女在线| √新版天堂资源在线资源| 亚洲专区在线视频| 一区二区国产在线观看| 女人黄色一级片| 日韩欧美三级在线| **欧美日韩在线观看| 国产免费一区二区三区四在线播放| 成人性视频网站| 亚洲成人av网址| 欧美黑人巨大精品一区二区| 国产a久久精品一区二区三区| 亚洲妇熟xx妇色黄蜜桃| 午夜精品一区二区三区免费视频 | 午夜精品久久久久久久男人的天堂 | 在线天堂资源| 天天干天天色天天爽| 久久综合999| 国产成人精品av在线观| 国产成人精品免高潮费视频| 自拍日韩欧美| 欧美精品日韩在线| 亚洲精品av在线|