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

一篇帶給你 Sentinel 和常用流控算法

開發 前端 算法
本文主要講述常見的幾種限流算法:計數器算法、漏桶算法、令牌桶算法。然后結合我對 Sentinel 1.8.0 的理解,給大家分享 Sentinel 在源碼中如何使用這些算法進行流控判斷。

[[401361]]

本文主要講述常見的幾種限流算法:計數器算法、漏桶算法、令牌桶算法。然后結合我對 Sentinel 1.8.0 的理解,給大家分享 Sentinel 在源碼中如何使用這些算法進行流控判斷。

計數器限流算法

我們可以直接通過一個計數器,限制每一秒鐘能夠接收的請求數。比如說 qps定為 1000,那么實現思路就是從第一個請求進來開始計時,在接下去的 1s 內,每來一個請求,就把計數加 1,如果累加的數字達到了 1000,那么后續的請求就會被全部拒絕。等到 1s 結束后,把計數恢復成 0 ,重新開始計數。

優點:實現簡單

缺點:如果1s 內的前半秒,已經通過了 1000 個請求,那后面的半秒只能請求拒絕,我們把這種現象稱為“突刺現象”。

實現代碼案例:

  1. public class Counter { 
  2.     public long timeStamp = getNowTime(); 
  3.     public int reqCount = 0; 
  4.     public final int limit = 100; // 時間窗口內最大請求數 
  5.     public final long interval = 1000; // 時間窗口ms 
  6.  
  7.     public boolean limit() { 
  8.         long now = getNowTime(); 
  9.         if (now < timeStamp + interval) { 
  10.             // 在時間窗口內 
  11.             reqCount++; 
  12.             // 判斷當前時間窗口內是否超過最大請求控制數 
  13.             return reqCount <= limit; 
  14.         } else { 
  15.             timeStamp = now; 
  16.             // 超時后重置 
  17.             reqCount = 1; 
  18.             return true
  19.         } 
  20.     } 
  21.  
  22.     public long getNowTime() { 
  23.         return System.currentTimeMillis(); 
  24.     } 

滑動時間窗算法

滑動窗口,又稱 Rolling Window。為了解決計數器算法的缺陷,我們引入了滑動窗口算法。下面這張圖,很好地解釋了滑動窗口算法:

在上圖中,整個紅色的矩形框表示一個時間窗口,在我們的例子中,一個時間窗口就是一分鐘。然后我們將時間窗口進行劃分,比如圖中,我們就將滑動窗口 劃成了6格,所以每格代表的是10秒鐘。每過10秒鐘,我們的時間窗口就會往右滑動一格。每一個格子都有自己獨立的計數器counter,比如當一個請求 在0:35秒的時候到達,那么0:30~0:39對應的counter就會加1。

那么滑動窗口怎么解決剛才的臨界問題的呢?我們可以看上圖,0:59到達的100個請求會落在灰色的格子中,而1:00到達的請求會落在橘黃色的格子中。當時間到達1:00時,我們的窗口會往右移動一格,那么此時時間窗口內的總請求數量一共是200個,超過了限定的100個,所以此時能夠檢測出來觸發了限流。

我再來回顧一下剛才的計數器算法,我們可以發現,計數器算法其實就是滑動窗口算法。只是它沒有對時間窗口做進一步地劃分,所以只有1格。

由此可見,當滑動窗口的格子劃分的越多,那么滑動窗口的滾動就越平滑,限流的統計就會越精確。

實現代碼案例:

  1. public class SlideWindow { 
  2.  
  3.     /** 隊列id和隊列的映射關系,隊列里面存儲的是每一次通過時候的時間戳,這樣可以使得程序里有多個限流隊列 */ 
  4.     private volatile static Map<String, List<Long>> MAP = new ConcurrentHashMap<>(); 
  5.  
  6.     private SlideWindow() {} 
  7.  
  8.     public static void main(String[] args) throws InterruptedException { 
  9.         while (true) { 
  10.             // 任意10秒內,只允許2次通過 
  11.             System.out.println(LocalTime.now().toString() + SlideWindow.isGo("ListId", 2, 10000L)); 
  12.             // 睡眠0-10秒 
  13.             Thread.sleep(1000 * new Random().nextInt(10)); 
  14.         } 
  15.     } 
  16.  
  17.     /** 
  18.      * 滑動時間窗口限流算法 
  19.      * 在指定時間窗口,指定限制次數內,是否允許通過 
  20.      * 
  21.      * @param listId     隊列id 
  22.      * @param count      限制次數 
  23.      * @param timeWindow 時間窗口大小 
  24.      * @return 是否允許通過 
  25.      */ 
  26.     public static synchronized boolean isGo(String listId, int count, long timeWindow) { 
  27.         // 獲取當前時間 
  28.         long nowTime = System.currentTimeMillis(); 
  29.         // 根據隊列id,取出對應的限流隊列,若沒有則創建 
  30.         List<Long> list = MAP.computeIfAbsent(listId, k -> new LinkedList<>()); 
  31.         // 如果隊列還沒滿,則允許通過,并添加當前時間戳到隊列開始位置 
  32.         if (list.size() < count) { 
  33.             list.add(0, nowTime); 
  34.             return true
  35.         } 
  36.  
  37.         // 隊列已滿(達到限制次數),則獲取隊列中最早添加的時間戳 
  38.         Long farTime = list.get(count - 1); 
  39.         // 用當前時間戳 減去 最早添加的時間戳 
  40.         if (nowTime - farTime <= timeWindow) { 
  41.             // 若結果小于等于timeWindow,則說明在timeWindow內,通過的次數大于count 
  42.             // 不允許通過 
  43.             return false
  44.         } else { 
  45.             // 若結果大于timeWindow,則說明在timeWindow內,通過的次數小于等于count 
  46.             // 允許通過,并刪除最早添加的時間戳,將當前時間添加到隊列開始位置 
  47.             list.remove(count - 1); 
  48.             list.add(0, nowTime); 
  49.             return true
  50.         } 
  51.     } 
  52.  

在 Sentinel 中 通過 LeapArray 結構來實現時間窗算法, 它的核心代碼如下(只列舉獲取時間窗方法):

  1. /** 
  2.      * 獲取當前的時間窗 
  3.      * 
  4.      * Get bucket item at provided timestamp
  5.      * 
  6.      * @param timeMillis a valid timestamp in milliseconds 
  7.      * @return current bucket item at provided timestamp if the time is valid; null if time is invalid 
  8.      */ 
  9. public WindowWrap<T> currentWindow(long timeMillis) { 
  10.   if (timeMillis < 0) { 
  11.     return null
  12.   } 
  13.  
  14.   int idx = calculateTimeIdx(timeMillis); 
  15.   // Calculate current bucket start time
  16.   // 計算窗口的開始時間,計算每個格子的開始時間 
  17.   long windowStart = calculateWindowStart(timeMillis); 
  18.  
  19.   /* 
  20.          * Get bucket item at given time from the array. 
  21.          * 
  22.          * (1) Bucket is absent, then just create a new bucket and CAS update to circular array. 
  23.          * (2) Bucket is up-to-datethen just return the bucket. 
  24.          * (3) Bucket is deprecated, then reset current bucket and clean all deprecated buckets. 
  25.          */ 
  26.   while (true) { 
  27.     WindowWrap<T> old = array.get(idx); 
  28.     // 如果沒有窗格,創建窗格 
  29.     if (old == null) { 
  30.       /* 
  31.                  *     B0       B1      B2    NULL      B4 
  32.                  * ||_______|_______|_______|_______|_______||___ 
  33.                  * 200     400     600     800     1000    1200  timestamp 
  34.                  *                             ^ 
  35.                  *                          time=888 
  36.                  *            bucket is empty, so create new and update 
  37.                  * 
  38.                  * If the old bucket is absent, then we create a new bucket at {@code windowStart}, 
  39.                  * then try to update circular array via a CAS operation. Only one thread can 
  40.                  * succeed to update, while other threads yield its time slice. 
  41.                  */ 
  42.       WindowWrap<T> window = new WindowWrap<T>(windowLengthInMs, windowStart, newEmptyBucket(timeMillis)); 
  43.       if (array.compareAndSet(idx, null, window)) { 
  44.         // Successfully updated, return the created bucket. 
  45.         return window; 
  46.       } else { 
  47.         // Contention failed, the thread will yield its time slice to wait for bucket available. 
  48.         Thread.yield(); 
  49.       } 
  50.       // 當前窗格存在,返回歷史窗格 
  51.     } else if (windowStart == old.windowStart()) { 
  52.       /* 
  53.                  *     B0       B1      B2     B3      B4 
  54.                  * ||_______|_______|_______|_______|_______||___ 
  55.                  * 200     400     600     800     1000    1200  timestamp 
  56.                  *                             ^ 
  57.                  *                          time=888 
  58.                  *            startTime of Bucket 3: 800, so it's up-to-date 
  59.                  * 
  60.                  * If current {@code windowStart} is equal to the start timestamp of old bucket, 
  61.                  * that means the time is within the bucket, so directly return the bucket. 
  62.                  */ 
  63.       return old; 
  64.       // 
  65.     } else if (windowStart > old.windowStart()) { 
  66.       /* 
  67.                  *   (old) 
  68.                  *             B0       B1      B2    NULL      B4 
  69.                  * |_______||_______|_______|_______|_______|_______||___ 
  70.                  * ...    1200     1400    1600    1800    2000    2200  timestamp 
  71.                  *                              ^ 
  72.                  *                           time=1676 
  73.                  *          startTime of Bucket 2: 400, deprecated, should be reset 
  74.                  * 
  75.                  * If the start timestamp of old bucket is behind provided time, that means 
  76.                  * the bucket is deprecated. We have to reset the bucket to current {@code windowStart}. 
  77.                  * Note that the reset and clean-up operations are hard to be atomic, 
  78.                  * so we need a update lock to guarantee the correctness of bucket update
  79.                  * 
  80.                  * The update lock is conditional (tiny scope) and will take effect only when 
  81.                  * bucket is deprecated, so in most cases it won't lead to performance loss. 
  82.                  */ 
  83.       if (updateLock.tryLock()) { 
  84.         try { 
  85.           // Successfully get the update lock, now we reset the bucket. 
  86.           // 清空所有的窗格數據 
  87.           return resetWindowTo(old, windowStart); 
  88.         } finally { 
  89.           updateLock.unlock(); 
  90.         } 
  91.       } else { 
  92.         // Contention failed, the thread will yield its time slice to wait for bucket available. 
  93.         Thread.yield(); 
  94.       } 
  95.       // 如果時鐘回撥,重新創建時間格 
  96.     } else if (windowStart < old.windowStart()) { 
  97.       // Should not go through here, as the provided time is already behind. 
  98.       return new WindowWrap<T>(windowLengthInMs, windowStart, newEmptyBucket(timeMillis)); 
  99.     } 
  100.   } 

漏桶算法

漏桶算法(Leaky Bucket)是網絡世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)時經常使用的一種算法,它的主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便為網絡提供一個穩定的流量, 執行過程如下圖所示。

實現代碼案例:

  1. public class LeakyBucket { 
  2.   public long timeStamp = System.currentTimeMillis();  // 當前時間 
  3.   public long capacity; // 桶的容量 
  4.   public long rate; // 水漏出的速度 
  5.   public long water; // 當前水量(當前累積請求數) 
  6.  
  7.   public boolean grant() { 
  8.     long now = System.currentTimeMillis(); 
  9.     // 先執行漏水,計算剩余水量 
  10.     water = Math.max(0, water - (now - timeStamp) * rate);  
  11.  
  12.     timeStamp = now; 
  13.     if ((water + 1) < capacity) { 
  14.       // 嘗試加水,并且水還未滿 
  15.       water += 1; 
  16.       return true
  17.     } else { 
  18.       // 水滿,拒絕加水 
  19.       return false
  20.     } 
  21.   } 

說明:

(1)未滿加水:通過代碼 water +=1進行不停加水的動作。

(2)漏水:通過時間差來計算漏水量。

(3)剩余水量:總水量-漏水量。

在 Sentine 中RateLimiterController 實現了了漏桶算法 , 核心代碼如下

  1. @Override 
  2. public boolean canPass(Node node, int acquireCount, boolean prioritized) { 
  3.   // Pass when acquire count is less or equal than 0. 
  4.   if (acquireCount <= 0) { 
  5.     return true
  6.   } 
  7.   // Reject when count is less or equal than 0. 
  8.   // Otherwise,the costTime will be max of long and waitTime will overflow in some cases. 
  9.   if (count <= 0) { 
  10.     return false
  11.   } 
  12.  
  13.   long currentTime = TimeUtil.currentTimeMillis(); 
  14.   // Calculate the interval between every two requests. 
  15.   // 計算時間間隔 
  16.   long costTime = Math.round(1.0 * (acquireCount) / count * 1000); 
  17.  
  18.   // Expected pass time of this request. 
  19.   // 期望的執行時間 
  20.   long expectedTime = costTime + latestPassedTime.get(); 
  21.  
  22.   // 當前時間 > 期望時間 
  23.   if (expectedTime <= currentTime) { 
  24.     // Contention may exist here, but it's okay. 
  25.     // 可以通過,并且設置最后通過時間 
  26.     latestPassedTime.set(currentTime); 
  27.     return true
  28.   } else { 
  29.     // Calculate the time to wait. 
  30.     // 等待時間 = 期望時間 - 最后時間 - 當前時間 
  31.     long waitTime = costTime + latestPassedTime.get() - TimeUtil.currentTimeMillis(); 
  32.     // 等待時間 > 最大排隊時間 
  33.     if (waitTime > maxQueueingTimeMs) { 
  34.       return false
  35.     } else { 
  36.       // 上次時間 + 間隔時間 
  37.       long oldTime = latestPassedTime.addAndGet(costTime); 
  38.       try { 
  39.         // 等待時間 
  40.         waitTime = oldTime - TimeUtil.currentTimeMillis(); 
  41.         // 等待時間 > 最大排隊時間 
  42.         if (waitTime > maxQueueingTimeMs) { 
  43.           latestPassedTime.addAndGet(-costTime); 
  44.           return false
  45.         } 
  46.         // in race condition waitTime may <= 0 
  47.         // 休眠等待 
  48.         if (waitTime > 0) { 
  49.           Thread.sleep(waitTime); 
  50.         } 
  51.         // 等待完了,就放行 
  52.         return true
  53.       } catch (InterruptedException e) { 
  54.       } 
  55.     } 
  56.   } 
  57.   return false

令牌桶算法

令牌桶算法是網絡流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一種算法。典型情況下,令牌桶算法用來控制發送到網絡上的數據的數目,并允許突發數據的發送。如下圖所示:

簡單的說就是,一邊請求時會消耗桶內的令牌,另一邊會以固定速率往桶內放令牌。當消耗的請求大于放入的速率時,進行相應的措施,比如等待,或者拒絕等。

實現代碼案例:

  1. public class TokenBucket { 
  2.   public long timeStamp = System.currentTimeMillis();  // 當前時間 
  3.   public long capacity; // 桶的容量 
  4.   public long rate; // 令牌放入速度 
  5.   public long tokens; // 當前令牌數量 
  6.  
  7.   public boolean grant() { 
  8.     long now = System.currentTimeMillis(); 
  9.     // 先添加令牌 
  10.     tokens = Math.min(capacity, tokens + (now - timeStamp) * rate); 
  11.     timeStamp = now; 
  12.     if (tokens < 1) { 
  13.       // 若不到1個令牌,則拒絕 
  14.       return false
  15.     } else { 
  16.       // 還有令牌,領取令牌 
  17.       tokens -= 1; 
  18.       return true
  19.     } 
  20.   } 

Sentinel 在 WarmUpController 中運用到了令牌桶算法,在這里可以實現對系統的預熱,設定預熱時間和水位線,對于預熱期間多余的請求直接拒絕掉。

  1. public boolean canPass(Node node, int acquireCount, boolean prioritized) { 
  2.   long passQps = (long) node.passQps(); 
  3.  
  4.   long previousQps = (long) node.previousPassQps(); 
  5.   syncToken(previousQps); 
  6.  
  7.   // 開始計算它的斜率 
  8.   // 如果進入了警戒線,開始調整他的qps 
  9.   long restToken = storedTokens.get(); 
  10.   if (restToken >= warningToken) { 
  11.     long aboveToken = restToken - warningToken; 
  12.     // 消耗的速度要比warning快,但是要比慢 
  13.     // current interval = restToken*slope+1/count 
  14.     double warningQps = Math.nextUp(1.0 / (aboveToken * slope + 1.0 / count)); 
  15.     if (passQps + acquireCount <= warningQps) { 
  16.       return true
  17.     } 
  18.   } else { 
  19.     if (passQps + acquireCount <= count) { 
  20.       return true
  21.     } 
  22.   } 
  23.  
  24.   return false

限流算法總結

計數器 VS 時間窗

時間窗算法的本質也是通過計數器算法實現的。

時間窗算法格子劃分的越多,那么滑動窗口的滾動就越平滑,限流的統計就會越精確,但是也會占用更多的內存存儲。

漏桶 VS 令牌桶

漏桶算法和令牌桶算法本質上是為了做流量整形或速率限制,避免系統因為大流量而被打崩,但是兩者的核心差異在于限流的方向是相反的

漏桶:限制的是流量的流出速率,是相對固定的。

令牌桶 :限制的是流量的平均流入速率,并且允許一定程度的突然性流量,最大速率為桶的容量和生成token的速率。

在某些場景中,漏桶算法并不能有效的使用網絡資源,因為漏桶的漏出速率是相對固定的,所以在網絡情況比較好并且沒有擁塞的狀態下,漏桶依然是會有限制的,并不能放開量,因此并不能有效的利用網絡資源。而令牌桶算法則不同,其在限制平均速率的同時,支持一定程度的突發流量。

參考文檔

https://www.cnblogs.com/linjiqin/p/9707713.html

https://www.cnblogs.com/dijia478/p/13807826.html

 

責任編輯:姜華 來源: 運維開發故事
相關推薦

2021-05-24 08:09:21

SentinelRedis 流控原理

2021-07-12 06:11:14

SkyWalking 儀表板UI篇

2023-03-09 07:47:56

BeanFactorSpring框架

2022-04-27 09:09:57

架構師術語技術語言

2022-04-29 14:38:49

class文件結構分析

2021-04-14 14:16:58

HttpHttp協議網絡協議

2021-04-08 11:00:56

CountDownLaJava進階開發

2022-02-17 08:53:38

ElasticSea集群部署

2021-04-01 10:51:55

MySQL鎖機制數據庫

2021-07-21 09:48:20

etcd-wal模塊解析數據庫

2024-06-13 08:34:48

2022-03-22 09:09:17

HookReact前端

2021-01-28 08:55:48

Elasticsear數據庫數據存儲

2023-03-29 07:45:58

VS編輯區編程工具

2021-03-12 09:21:31

MySQL數據庫邏輯架構

2021-06-21 14:36:46

Vite 前端工程化工具

2022-05-08 19:36:35

Web前端時間復雜度

2021-04-14 07:55:45

Swift 協議Protocol

2021-05-08 08:36:40

ObjectString前端

2021-07-08 07:30:13

Webpack 前端Tree shakin
點贊
收藏

51CTO技術棧公眾號

91片黄在线观看| 视频精品在线观看| 亚洲一区二区三区不卡国产欧美| 91天堂在线视频| 久久久久人妻一区精品色欧美| 日韩成人精品一区二区三区| 日韩美女精品在线| 粉嫩av免费一区二区三区| 欧美色图亚洲天堂| 自拍视频一区| 欧美日韩亚洲高清一区二区| 丰满人妻一区二区三区53号| 欧美一级特黄aaaaaa| 久久久久久亚洲精品杨幂换脸| 在线电影av不卡网址| 熟妇人妻va精品中文字幕| 97超碰国产一区二区三区| 精品一区二区三区不卡| 国内精品久久久久久影视8| 中文在线永久免费观看| 欧美a一级片| 一区二区三区毛片| 日本一区二区三区四区高清视频| a天堂在线视频| 国产精品一级| 一区二区三区黄色| 国产精品成人免费一区久久羞羞| 深夜av在线| 一区二区中文字幕在线| 精品国产91亚洲一区二区三区www| 无码人妻久久一区二区三区| 综合久久综合| 中国china体内裑精亚洲片| 91亚洲一线产区二线产区 | 日韩精品专区| 一区二区三区资源| 亚洲精品影院| 日本不卡视频一区二区| 国产mv日韩mv欧美| 3344国产精品免费看| 999精品在线视频| 国产一区二区三区四区五区| 精品国产99国产精品| 少妇一级淫免费播放| 黄毛片在线观看| 夜夜夜精品看看| 一区二区三区国产福利| 邻居大乳一区二区三区| 国产精品18久久久久久vr| 国产精品电影观看| 男人午夜免费视频| 最新亚洲一区| 欧美高清视频在线| 91视频综合网| 欧美在线91| 久久精品亚洲国产| 夫妇露脸对白88av| 亚洲婷婷影院| 日韩av中文字幕在线免费观看| 国产精品嫩草69影院| 日本精品在线播放| 777精品伊人久久久久大香线蕉| 国产真实乱子伦| 男人天堂视频在线观看| 性欧美大战久久久久久久久| 蜜桃视频一区二区在线观看| 免费观看久久久久| 国产精品美女久久久久久久网站| 欧美一区二区综合| 男男激情在线| 国产女人18毛片水真多成人如厕| 久久精品美女| 日本1级在线| 久久久99久久| 午夜精品一区二区三区四区| 性感美女一级片| 99re这里都是精品| 欧美日韩国产综合视频在线| 久久天堂电影| 日本一区二区三区免费乱视频 | 国产免费成人在线视频| 国产亚洲一区二区三区在线播放| 亚洲男女视频在线观看| 成人激情综合网站| 狠狠色伊人亚洲综合网站色| 亚洲欧洲精品视频| 国产亚洲欧美激情| 亚洲视频电影| 3d玉蒲团在线观看| 精品国产乱码久久久久久虫虫漫画 | 涩涩涩久久久成人精品| 91麻豆精品国产91久久久资源速度| 91小视频在线播放| 欧洲美女精品免费观看视频| 91精品国产综合久久久蜜臀粉嫩| www.色.com| 嫩草国产精品入口| 在线观看国产精品91| 亚洲 欧美 变态 另类 综合| 欧美全黄视频| 97超级碰碰人国产在线观看| 久久久久在线视频| 国产在线视频不卡二| 国产精品免费在线播放| 国产露出视频在线观看| 日本一区二区动态图| 亚洲五码在线观看视频| 免费观看一级欧美片| 欧美日韩aaa| 在线观看免费视频国产| 国产精品嫩模av在线| 久久国产精品网站| 综合网在线观看| 蜜臀a∨国产成人精品| 古典武侠综合av第一页| 国产资源在线播放| 亚洲欧美日韩系列| 少妇高潮喷水久久久久久久久久| 欧美日韩破处视频| 亚洲成色777777在线观看影院| 日本一区二区在线免费观看| 欧美激情777| 57pao成人永久免费视频| 在线播放国产一区| jlzzjlzz国产精品久久| 中文字幕一区二区三区四区五区人| 欧美xxxx免费虐| 欧美色图在线观看| 中文字幕乱码在线| 久久久久国产| 国产福利视频一区二区| 欧美一级性视频| 亚洲柠檬福利资源导航| 激情婷婷综合网| 精品91福利视频| 夜夜嗨av一区二区三区免费区| 国产一级av毛片| 国产美女在线精品| 亚洲高清视频一区二区| 中文字幕一区久| 精品国产区一区| 成人黄色a级片| 噜噜爱69成人精品| 国产偷久久久精品专区| 成人短视频在线| 在线精品视频一区二区三四| 99久久久久久久久久| 韩日成人av| 91高跟黑色丝袜呻吟在线观看| av每日在线更新| 色婷婷综合五月| 久久精品女同亚洲女同13| 欧美一区影院| 91超碰在线电影| 国产精品剧情| 欧美久久久久中文字幕| 日韩免费成人av| 日韩电影在线观看一区| 欧美日韩喷水| 欧洲亚洲两性| 亚洲九九九在线观看| 日本va欧美va国产激情| av影院午夜一区| 视色,视色影院,视色影库,视色网| 国产亚洲精品精品国产亚洲综合| 国产一区二区欧美日韩| 草莓视频18免费观看| 91在线观看视频| 一女被多男玩喷潮视频| 日韩成人一级| 日韩av免费看网站| 国产在线观看精品一区| 欧美性生活影院| 精品亚洲乱码一区二区| 日本中文字幕一区| 亚洲一区二区不卡视频| 亚洲成人毛片| 欧美大片免费观看在线观看网站推荐| 国产成人久久精品77777综合| 夜夜嗨av一区二区三区网页| 色诱av手机版| 亚洲激情网站| 欧美大陆一区二区| 日韩av中字| 日韩一级裸体免费视频| 99在线精品视频免费观看20| 亚洲靠逼com| 97人妻精品一区二区三区免费| 1000部精品久久久久久久久| 欧美日韩国产免费一区二区三区| 成人国产精品入口免费视频| 久久网福利资源网站| 亚洲成人一级片| 欧美日韩在线看| 在线看黄色的网站| 久久在线精品| 9l视频自拍9l视频自拍| 亚洲网址在线观看| 国产69精品久久久久久| 亚洲s色大片| 精品日韩在线观看| 在线看成人av| 中文字幕av一区 二区| 可以看的av网址| 久久精品一区二区国产| 一区二区日本| 婷婷综合一区| 91香蕉亚洲精品| 日韩av激情| 一区二区三区高清国产| 亚洲乱色熟女一区二区三区| 日韩欧美在线免费| 国产精品 欧美激情| 26uuu精品一区二区| 国产精品探花在线播放| 久久国产精品久久w女人spa| 中文字幕欧美日韩一区二区三区 | 色呦呦一区二区三区| 侵犯稚嫩小箩莉h文系列小说| 99久久精品免费观看| wwwwwxxxx日本| 在线亚洲观看| 九一免费在线观看| 欧美日韩水蜜桃| 国产一级精品aaaaa看| 国产午夜久久av| 国产精品吊钟奶在线| 日本成人不卡| 精品国产一区二区三区久久久狼| 婷婷五月综合久久中文字幕| 欧美一区二区三区视频免费| 高潮无码精品色欲av午夜福利| 亚洲欧美激情在线| 欧美 日本 国产| 国产69精品久久久久777| 一级黄色录像在线观看| 亚洲永久免费| 欧美图片激情小说| 91精品国产乱码久久久久久| 日本亚洲自拍| 希岛爱理av免费一区二区| www.久久艹| 国产成人免费av一区二区午夜| 久久青草福利网站| av官网在线播放| www欧美日韩| 国产精品免费观看| 亚洲天堂男人天堂| 凸凹人妻人人澡人人添| 精品少妇一区二区三区在线播放 | 亚洲欧美不卡| 你懂的av在线| 亚洲视屏一区| 久久这里只有精品18| 菠萝蜜一区二区| 日韩视频在线播放| 成人同人动漫免费观看 | 伊人亚洲福利一区二区三区| 男人天堂亚洲二区| 亚洲视屏在线播放| 国产一级片在线| 亚洲精品短视频| 亚洲欧美日韩动漫| 亚洲欧美国产精品专区久久 | 风间由美性色一区二区三区 | 日本伊人精品一区二区三区观看方式| 116极品美女午夜一级| 老司机午夜精品视频| 国产偷人视频免费| 视频精品一区二区| 欧美婷婷精品激情| 久久精品国产99久久6| 成 人 黄 色 小说网站 s色| 国产在线一区观看| 少妇搡bbbb搡bbb搡打电话| 成人av电影在线| 欧美肉大捧一进一出免费视频| 91麻豆国产自产在线观看| 日韩一级视频在线观看| 国产欧美日韩久久| 成年人二级毛片| 亚洲午夜视频在线观看| www成人在线| 91成人在线观看喷潮| 日批视频免费观看| 日韩视频在线你懂得| 人妻夜夜爽天天爽| 亚洲老板91色精品久久| 91精品免费视频| 国模冰冰炮一区二区| 国产又爽又黄的激情精品视频| 99re6热只有精品免费观看| 麻豆91av| 中文字幕人成人乱码| 激情六月丁香婷婷| 国产精品综合久久| 久久久视频6r| 亚洲va国产va欧美va观看| 伊人久久成人网| 日韩国产高清视频在线| 福利在线视频网站| 国产成人激情视频| 白嫩白嫩国产精品| 在线观看欧美一区| 久久xxxx精品视频| 麻豆免费在线观看视频| 中日韩av电影| 久久精品久久久久久久| 亚洲第一福利在线观看| 成人影院在线观看| 国产精品高潮粉嫩av| 美女视频亚洲色图| 免费的av在线| 免费成人美女在线观看| 性欧美13一14内谢| 午夜不卡av在线| 亚洲av无码专区在线| 精品国产视频在线| 91亚洲精品| 欧美人与物videos另类| 日韩天堂av| 高清中文字幕mv的电影| 亚洲欧美二区三区| 国产精品久久久久久久久毛片 | 波多野结衣家庭教师| 欧美怡红院视频| 国产色在线 com| 17婷婷久久www| 精品精品国产三级a∨在线| 4444亚洲人成无码网在线观看 | 国产精品边吃奶边做爽| 亚洲一区电影777| 精品黑人一区二区三区在线观看 | a成人v在线| 奇米影视首页 狠狠色丁香婷婷久久综合 | 国产一区二区三区在线免费| 久久99精品视频| 日本激情视频一区二区三区| 欧美日韩国产天堂| 欧美日韩在线资源| 92看片淫黄大片欧美看国产片| 97国产成人高清在线观看| 一区二区三区网址| 国产精品无人区| 91精品视频免费在线观看| 日韩在线视频中文字幕| 欧美日韩伦理一区二区| 偷拍盗摄高潮叫床对白清晰| 狠狠色伊人亚洲综合成人| www.av成人| 精品国产免费视频| 国产乱码精品一区二三赶尸艳谈| 精品国产日本| 视频一区二区欧美| 99久久精品久久亚洲精品| 欧美高清视频不卡网| av电影高清在线观看| 99久久综合狠狠综合久久止| 亚洲人成毛片在线播放女女| 黄色国产在线观看| 欧美亚洲国产bt| 麻豆av免费在线观看| 999视频在线观看| 亚洲第一黄网| 少妇无套高潮一二三区| 欧美精品高清视频| 伦理av在线| 欧美三日本三级少妇三99| 男女视频一区二区| 538精品在线观看| 精品香蕉在线观看视频一| 美女网站视频一区| 午夜久久久久久久久久久| 成人激情视频网站| 午夜久久久久久久久久影院| 久久久精品视频成人| 国产区精品视频在线观看豆花| 国产成人av影视| 亚洲欧美电影院| 牛牛影视精品影视| 成人综合国产精品| 亚洲国内精品| www中文在线| 亚洲第一网站免费视频| 日本一区二区三区视频在线| 久久久久久av无码免费网站下载| www.激情成人| 国产一区二区视频免费观看| 国内精品久久影院| 97在线精品| 黄色a一级视频| 6080国产精品一区二区| www.成人爱| 麻豆映画在线观看| 国产天堂亚洲国产碰碰| 国产91麻豆视频| 国产在线精品一区免费香蕉 | 天堂资源最新在线| 亚洲永久免费观看| 日韩高清在线观看|