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

基于Consul的分布式信號量實現(xiàn)

開發(fā) 開發(fā)工具 分布式
本文將繼續(xù)討論基于Consul的分布式鎖實現(xiàn)。信號量是我們在實現(xiàn)并發(fā)控制時會經(jīng)常使用的手段,主要用來限制同時并發(fā)線程或進程的數(shù)量。

本文將繼續(xù)討論基于Consul的分布式鎖實現(xiàn)。信號量是我們在實現(xiàn)并發(fā)控制時會經(jīng)常使用的手段,主要用來限制同時并發(fā)線程或進程的數(shù)量,比如:Zuul默認情況下就使用信號量來限制每個路由的并發(fā)數(shù),以實現(xiàn)不同路由間的資源隔離。

[[190924]]

信號量(Semaphore),有時被稱為信號燈,是在多線程環(huán)境下使用的一種設(shè)施,是可以用來保證兩個或多個關(guān)鍵代碼段不被并發(fā)調(diào)用。在進入一個關(guān)鍵代碼段之前,線程必須獲取一個信號量;一旦該關(guān)鍵代碼段完成了,那么該線程必須釋放信號量。其他想進入該關(guān)鍵代碼段的線程必須等待直到***個線程釋放信號量。為了完成這個過程,需要創(chuàng)建一個信號量VI,然后將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個關(guān)鍵代碼段的首末端,確認這些信號量VI引用的是初始創(chuàng)建的信號量。如在這個停車場系統(tǒng)中,車位是公共資源,每輛車好比一個線程,看門人起的就是信號量的作用。

實現(xiàn)思路

  1. 信號量存儲:semaphore/key
  2. acquired操作:
  3. 創(chuàng)建session
  4. 鎖定key競爭者:semaphore/key/session
  5. 查詢信號量:semaphore/key/.lock,可以獲得如下內(nèi)容(如果是***次創(chuàng)建信號量,將獲取不到,這個時候就直接創(chuàng)建)
    1.     "limit": 3, 
    2.     "holders": [ 
    3.         "90c0772a-4bd3-3a3c-8215-3b8937e36027", 
    4.         "93e5611d-5365-a374-8190-f80c4a7280ab" 
    5.     ] 
  6. 如果持有者已達上限,返回false,如果阻塞模式,就繼續(xù)嘗試acquired操作
  7. 如果持有者未達上限,更新semaphore/key/.lock的內(nèi)容,將當(dāng)前線程的sessionId加入到holders中。注意:更新的時候需要設(shè)置cas,它的值是“查詢信號量”步驟獲得的“ModifyIndex”值,該值用于保證更新操作的基礎(chǔ)沒有被其他競爭者更新。如果更新成功,就開始執(zhí)行具體邏輯。如果沒有更新成功,說明有其他競爭者搶占了資源,返回false,阻塞模式下繼續(xù)嘗試acquired操作
  8. release操作:
  • 從semaphore/key/.lock的holders中移除當(dāng)前sessionId
  • 刪除semaphore/key/session
  • 刪除當(dāng)前的session

流程圖

代碼實現(xiàn)

  1. public class Semaphore { 
  2.   
  3.     private Logger logger = Logger.getLogger(getClass()); 
  4.   
  5.     private static final String prefix = "semaphore/";  // 信號量參數(shù)前綴 
  6.   
  7.     private ConsulClient consulClient; 
  8.     private int limit; 
  9.     private String keyPath; 
  10.     private String sessionId = null
  11.     private boolean acquired = false
  12.   
  13.     /** 
  14.      * 
  15.      * @param consulClient consul客戶端實例 
  16.      * @param limit 信號量上限值 
  17.      * @param keyPath 信號量在consul中存儲的參數(shù)路徑 
  18.      */ 
  19.     public Semaphore(ConsulClient consulClient, int limit, String keyPath) { 
  20.         this.consulClient = consulClient; 
  21.         this.limit = limit; 
  22.         this.keyPath = prefix + keyPath; 
  23.     } 
  24.   
  25.     /** 
  26.      * acquired信號量 
  27.      * 
  28.      * @param block 是否阻塞。如果為true,那么一直嘗試,直到獲取到該資源為止。 
  29.      * @return 
  30.      * @throws IOException 
  31.      */ 
  32.     public Boolean acquired(boolean block) throws IOException { 
  33.   
  34.         if(acquired) { 
  35.             logger.error(sessionId + " - Already acquired"); 
  36.             throw new RuntimeException(sessionId + " - Already acquired"); 
  37.         } 
  38.   
  39.         // create session 
  40.         clearSession(); 
  41.         this.sessionId = createSessionId("semaphore"); 
  42.         logger.debug("Create session : " + sessionId); 
  43.   
  44.         // add contender entry 
  45.         String contenderKey = keyPath + "/" + sessionId; 
  46.         logger.debug("contenderKey : " + contenderKey); 
  47.         PutParams putParams = new PutParams(); 
  48.         putParams.setAcquireSession(sessionId); 
  49.         Boolean b = consulClient.setKVValue(contenderKey, "", putParams).getValue(); 
  50.         if(!b) { 
  51.             logger.error("Failed to add contender entry : " + contenderKey + ", " + sessionId); 
  52.             throw new RuntimeException("Failed to add contender entry : " + contenderKey + ", " + sessionId); 
  53.         } 
  54.   
  55.         while(true) { 
  56.             // try to take the semaphore 
  57.             String lockKey = keyPath + "/.lock"; 
  58.             String lockKeyValue; 
  59.   
  60.             GetValue lockKeyContent = consulClient.getKVValue(lockKey).getValue(); 
  61.   
  62.             if (lockKeyContent != null) { 
  63.                 // lock值轉(zhuǎn)換 
  64.                 lockKeyValue = lockKeyContent.getValue(); 
  65.                 BASE64Decoder decoder = new BASE64Decoder(); 
  66.                 byte[] v = decoder.decodeBuffer(lockKeyValue); 
  67.                 String lockKeyValueDecode = new String(v); 
  68.                 logger.debug("lockKey=" + lockKey + "lockKeyValueDecode=" + lockKeyValueDecode); 
  69.   
  70.                 Gson gson = new Gson(); 
  71.                 ContenderValue contenderValue = gson.fromJson(lockKeyValueDecode, ContenderValue.class); 
  72.                 // 當(dāng)前信號量已滿 
  73.                 if(contenderValue.getLimit() == contenderValue.getHolders().size()) { 
  74.                     logger.debug("Semaphore limited " + contenderValue.getLimit() + ", waiting..."); 
  75.                     if(block) { 
  76.                         // 如果是阻塞模式,再嘗試 
  77.                         try { 
  78.                             Thread.sleep(100L); 
  79.                         } catch (InterruptedException e) { 
  80.                         } 
  81.                         continue; 
  82.                     } 
  83.                     // 非阻塞模式,直接返回沒有獲取到信號量 
  84.                     return false; 
  85.                 } 
  86.                 // 信號量增加 
  87.                 contenderValue.getHolders().add(sessionId); 
  88.                 putParams = new PutParams(); 
  89.                 putParams.setCas(lockKeyContent.getModifyIndex()); 
  90.                 boolean c = consulClient.setKVValue(lockKey, contenderValue.toString(), putParams).getValue(); 
  91.                 if(c) { 
  92.                     acquired = true
  93.                     return true; 
  94.                 } 
  95.                 else 
  96.                     continue; 
  97.             } else { 
  98.                 // 當(dāng)前信號量還沒有,所以創(chuàng)建一個,并馬上搶占一個資源 
  99.                 ContenderValue contenderValue = new ContenderValue(); 
  100.                 contenderValue.setLimit(limit); 
  101.                 contenderValue.getHolders().add(sessionId); 
  102.   
  103.                 putParams = new PutParams(); 
  104.                 putParams.setCas(0L); 
  105.                 boolean c = consulClient.setKVValue(lockKey, contenderValue.toString(), putParams).getValue(); 
  106.                 if (c) { 
  107.                     acquired = true
  108.                     return true; 
  109.                 } 
  110.                 continue; 
  111.             } 
  112.         } 
  113.     } 
  114.   
  115.     /** 
  116.      * 創(chuàng)建sessionId 
  117.      * @param sessionName 
  118.      * @return 
  119.      */ 
  120.     public String createSessionId(String sessionName) { 
  121.         NewSession newnewSession = new NewSession(); 
  122.         newSession.setName(sessionName); 
  123.         return consulClient.sessionCreate(newSession, null).getValue(); 
  124.     } 
  125.   
  126.     /** 
  127.      * 釋放session、并從lock中移除當(dāng)前的sessionId 
  128.      * @throws IOException 
  129.      */ 
  130.     public void release() throws IOException { 
  131.         if(this.acquired) { 
  132.             // remove session from lock 
  133.             while(true) { 
  134.                 String contenderKey = keyPath + "/" + sessionId; 
  135.                 String lockKey = keyPath + "/.lock"; 
  136.                 String lockKeyValue; 
  137.   
  138.                 GetValue lockKeyContent = consulClient.getKVValue(lockKey).getValue(); 
  139.                 if (lockKeyContent != null) { 
  140.                     // lock值轉(zhuǎn)換 
  141.                     lockKeyValue = lockKeyContent.getValue(); 
  142.                     BASE64Decoder decoder = new BASE64Decoder(); 
  143.                     byte[] v = decoder.decodeBuffer(lockKeyValue); 
  144.                     String lockKeyValueDecode = new String(v); 
  145.                     Gson gson = new Gson(); 
  146.                     ContenderValue contenderValue = gson.fromJson(lockKeyValueDecode, ContenderValue.class); 
  147.                     contenderValue.getHolders().remove(sessionId); 
  148.                     PutParams putParams = new PutParams(); 
  149.                     putParams.setCas(lockKeyContent.getModifyIndex()); 
  150.                     consulClient.deleteKVValue(contenderKey); 
  151.                     boolean c = consulClient.setKVValue(lockKey, contenderValue.toString(), putParams).getValue(); 
  152.                     if(c) { 
  153.                         break; 
  154.                     } 
  155.                 } 
  156.             } 
  157.             // remove session key 
  158.   
  159.         } 
  160.         this.acquired = false
  161.         clearSession(); 
  162.     } 
  163.   
  164.     public void clearSession() { 
  165.         if(sessionId != null) { 
  166.             consulClient.sessionDestroy(sessionId, null); 
  167.             sessionId = null
  168.         } 
  169.     } 
  170.   
  171.     class ContenderValue implements Serializable { 
  172.   
  173.         private Integer limit; 
  174.         private List<String> holders = new ArrayList<>(); 
  175.   
  176.         public Integer getLimit() { 
  177.             return limit; 
  178.         } 
  179.   
  180.         public void setLimit(Integer limit) { 
  181.             this.limit = limit; 
  182.         } 
  183.   
  184.         public List<String> getHolders() { 
  185.             return holders; 
  186.         } 
  187.   
  188.         public void setHolders(List<String> holders) { 
  189.             this.holders = holders; 
  190.         } 
  191.   
  192.         @Override 
  193.         public String toString() { 
  194.             return new Gson().toJson(this); 
  195.         } 
  196.   
  197.     } 
  198.   

單元測試 

下面單元測試的邏輯:通過線程的方式來模擬不同的分布式服務(wù)來獲取信號量執(zhí)行業(yè)務(wù)邏輯。由于信號量與簡單的分布式互斥鎖有所不同,它不是只限定一個線程可以操作,而是可以控制多個線程的并發(fā),所以通過下面的單元測試,我們設(shè)置信號量為3,然后同時啟動15個線程來競爭的情況,來觀察分布式信號量實現(xiàn)的結(jié)果如何。

  1. INFO  [Thread-6] SemaphoreRunner - Thread 7 start! 
  2. INFO  [Thread-2] SemaphoreRunner - Thread 3 start! 
  3. INFO  [Thread-7] SemaphoreRunner - Thread 8 start! 
  4. INFO  [Thread-2] SemaphoreRunner - Thread 3 end! 
  5. INFO  [Thread-5] SemaphoreRunner - Thread 6 start! 
  6. INFO  [Thread-6] SemaphoreRunner - Thread 7 end! 
  7. INFO  [Thread-9] SemaphoreRunner - Thread 10 start! 
  8. INFO  [Thread-5] SemaphoreRunner - Thread 6 end! 
  9. INFO  [Thread-1] SemaphoreRunner - Thread 2 start! 
  10. INFO  [Thread-7] SemaphoreRunner - Thread 8 end! 
  11. INFO  [Thread-10] SemaphoreRunner - Thread 11 start! 
  12. INFO  [Thread-10] SemaphoreRunner - Thread 11 end! 
  13. INFO  [Thread-12] SemaphoreRunner - Thread 13 start! 
  14. INFO  [Thread-1] SemaphoreRunner - Thread 2 end! 
  15. INFO  [Thread-3] SemaphoreRunner - Thread 4 start! 
  16. INFO  [Thread-9] SemaphoreRunner - Thread 10 end! 
  17. INFO  [Thread-0] SemaphoreRunner - Thread 1 start! 
  18. INFO  [Thread-3] SemaphoreRunner - Thread 4 end! 
  19. INFO  [Thread-14] SemaphoreRunner - Thread 15 start! 
  20. INFO  [Thread-12] SemaphoreRunner - Thread 13 end! 
  21. INFO  [Thread-0] SemaphoreRunner - Thread 1 end! 
  22. INFO  [Thread-13] SemaphoreRunner - Thread 14 start! 
  23. INFO  [Thread-11] SemaphoreRunner - Thread 12 start! 
  24. INFO  [Thread-13] SemaphoreRunner - Thread 14 end! 
  25. INFO  [Thread-4] SemaphoreRunner - Thread 5 start! 
  26. INFO  [Thread-4] SemaphoreRunner - Thread 5 end! 
  27. INFO  [Thread-8] SemaphoreRunner - Thread 9 start! 
  28. INFO  [Thread-11] SemaphoreRunner - Thread 12 end! 
  29. INFO  [Thread-14] SemaphoreRunner - Thread 15 end! 
  30. INFO  [Thread-8] SemaphoreRunner - Thread 9 end! 
  1. public class TestLock { 
  2.   
  3.     private Logger logger = Logger.getLogger(getClass()); 
  4.   
  5.     @Test 
  6.     public void testSemaphore() throws Exception { 
  7.         new Thread(new SemaphoreRunner(1)).start(); 
  8.         new Thread(new SemaphoreRunner(2)).start(); 
  9.         new Thread(new SemaphoreRunner(3)).start(); 
  10.         new Thread(new SemaphoreRunner(4)).start(); 
  11.         new Thread(new SemaphoreRunner(5)).start(); 
  12.         new Thread(new SemaphoreRunner(6)).start(); 
  13.         new Thread(new SemaphoreRunner(7)).start(); 
  14.         new Thread(new SemaphoreRunner(8)).start(); 
  15.         new Thread(new SemaphoreRunner(9)).start(); 
  16.         new Thread(new SemaphoreRunner(10)).start(); 
  17.         Thread.sleep(1000000L); 
  18.     }  
  19.    
  20. public class SemaphoreRunner implements Runnable { 
  21.   
  22.     private Logger logger = Logger.getLogger(getClass()); 
  23.   
  24.     private int flag; 
  25.   
  26.     public SemaphoreRunner(int flag) { 
  27.         this.flag = flag; 
  28.     } 
  29.   
  30.     @Override 
  31.     public void run() { 
  32.         Semaphore semaphore = new Semaphore(new ConsulClient(), 3, "mg-init"); 
  33.         try { 
  34.             if (semaphore.acquired(true)) { 
  35.                 // 獲取到信號量,執(zhí)行業(yè)務(wù)邏輯 
  36.                 logger.info("Thread " + flag + " start!"); 
  37.                 Thread.sleep(new Random().nextInt(10000)); 
  38.                 logger.info("Thread " + flag + " end!"); 
  39.             } 
  40.         } catch (Exception e) { 
  41.             e.printStackTrace(); 
  42.         } finally { 
  43.             try { 
  44.                 // 信號量釋放、Session鎖釋放、Session刪除 
  45.                 semaphore.release(); 
  46.             } catch (IOException e) { 
  47.                 e.printStackTrace(); 
  48.             } 
  49.         } 
  50.     } 

從測試結(jié)果,我們可以發(fā)現(xiàn)當(dāng)信號量持有者數(shù)量達到信號量上限3的時候,其他競爭者就開始進行等待了,只有當(dāng)某個持有者釋放信號量之后,才會有新的線程變成持有者,從而開始執(zhí)行自己的業(yè)務(wù)邏輯。所以,分布式信號量可以幫助我們有效的控制同時操作某個共享資源的并發(fā)數(shù)。

優(yōu)化建議

同前文一樣,這里只是做了簡單的實現(xiàn)。線上應(yīng)用還必須加入TTL的session清理以及對.lock資源中的無效holder進行清理的機制。

參考文檔:https://www.consul.io/docs/guides/semaphore.html

實現(xiàn)代碼

【本文為51CTO專欄作者“翟永超”的原創(chuàng)稿件,轉(zhuǎn)載請通過51CTO聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2017-04-13 10:51:09

Consul分布式

2010-04-21 16:25:13

Unix信號量

2010-04-21 16:42:48

Unix信號量

2025-05-16 08:58:47

Mongodb分布式存儲

2022-10-27 10:44:14

分布式Zookeeper

2021-04-13 09:20:15

鴻蒙HarmonyOS應(yīng)用開發(fā)

2020-11-05 09:59:24

Linux內(nèi)核信號量

2010-04-21 16:50:31

Unix信號量

2009-06-19 14:23:41

RMIJava分布式計算

2023-01-06 09:19:12

Seata分布式事務(wù)

2015-04-21 09:39:03

javajava分布式爬蟲

2017-10-24 11:28:23

Zookeeper分布式鎖架構(gòu)

2021-09-07 07:53:42

Semaphore 信號量源碼

2020-09-25 07:34:40

Linux系統(tǒng)編程信號量

2010-04-21 15:37:38

Unix信號量

2022-11-06 19:28:02

分布式鎖etcd云原生

2009-12-08 12:14:43

2013-08-21 14:06:05

iOS隊列信號

2022-03-08 15:24:23

BitMapRedis數(shù)據(jù)

2025-04-01 00:44:04

點贊
收藏

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

久久久久人妻一区精品色欧美| 性活交片大全免费看| 77导航福利在线| 国产精品一区三区| 2019中文在线观看| 国产精品视频在| 国产精品极品国产中出| 日本精品一级二级| 9191国产视频| 成av人电影在线观看| 国产91丝袜在线观看| 国产成人精品在线播放| 久久国产波多野结衣| 天堂在线精品| 精品久久久久久久久久久久包黑料| 欧美日韩第二页| 性爱视频在线播放| 国产精品视频一二| 国产日本一区二区三区| 亚洲在线精品视频| 久久av在线| 97高清免费视频| 欧美色图亚洲视频| 欧美呦呦网站| 亚洲精品一区二区三区婷婷月| 波多野结衣网页| 少妇高潮一区二区三区99| 欧美性jizz18性欧美| 大胆欧美熟妇xx| 毛片网站在线免费观看| 91免费观看国产| 国产精品麻豆免费版| 国产精品欧美综合亚洲| 秋霞午夜鲁丝一区二区老狼| 26uuu国产精品视频| 欧美三级小视频| 欧美黄色大片在线观看| 亚洲最大中文字幕| 丰满少妇一区二区三区| 成人在线tv视频| 日韩欧美国产高清| 亚洲色图偷拍视频| 日韩免费在线电影| 欧美日韩国产小视频| 亚洲色图38p| 成人日韩精品| 在线亚洲一区观看| 亚洲男人天堂色| 国产成人精品一区二区三区在线| 色伊人久久综合中文字幕| 久久久久久久久久久久久国产精品| 岛国在线视频网站| 午夜国产不卡在线观看视频| 欧美 日韩 国产精品| 在线观看小视频| 亚洲制服丝袜av| 男人天堂手机在线视频| 国产色播av在线| 欧美日韩国产一区中文午夜| 国产aaa一级片| av激情成人网| 在线播放视频一区| 黄色a级三级三级三级| 91精品亚洲一区在线观看| 777亚洲妇女| 国产成人精品综合久久久久99| 日韩中文字幕一区二区高清99| 日韩欧美一级片| 欧美双性人妖o0| 亚洲动漫精品| xvideos亚洲人网站| 欧美成欧美va| 亚洲综合好骚| 国产精品美女午夜av| 国产精品亚洲欧美在线播放| 国产精品一区二区三区四区| 精品国产一区二区三区日日嗨| 亚洲 国产 欧美 日韩| 久久精品一区二区三区不卡| 亚洲午夜在线观看| 欧美极品少妇videossex| 图片区日韩欧美亚洲| 欧美 日韩 国产 激情| 日韩三区四区| 亚洲精品456在线播放狼人| av网站免费在线看| 亚洲国产老妈| 欧美一级大片视频| 亚洲天堂手机版| 成人免费视频一区| 色女人综合av| 美女网站视频在线| 日本高清不卡在线观看| 中文字幕欧美视频| 国产a久久精品一区二区三区| 日韩性xxxx爱| 在线观看亚洲天堂| 国内精品伊人久久久久影院对白| 国产v亚洲v天堂无码| 九九在线视频| 亚洲一级片在线观看| 亚洲成人av免费看| 老司机精品视频在线播放| 国产一区二区三区网站| 久久免费视频精品| 免费看欧美女人艹b| 国产精品日韩高清| 日本在线免费| 色综合久久六月婷婷中文字幕| 日本一二三四区视频| 欧美欧美黄在线二区| 欧美疯狂xxxx大交乱88av| 中文字幕观看视频| 99国产精品一区| 日本a级片在线观看| 国产成人精品一区二区三区在线 | 红桃av在线播放| 日韩精品中文字幕吗一区二区| 亚洲午夜未满十八勿入免费观看全集| 免费在线观看日韩| 极品少妇一区二区| 神马影院我不卡| 欧美日韩免费看片| 日韩激情视频在线| 精品少妇久久久| 国模大尺度一区二区三区| 欧美性大战久久久久| 波多一区二区| 日韩女优电影在线观看| 成人免费毛片xxx| 免费观看在线色综合| 免费不卡亚洲欧美| 原纱央莉成人av片| 日韩av影视综合网| 日韩精品手机在线| 99热这里都是精品| r级无码视频在线观看| 久久影院一区二区三区| 久久这里只有精品99| 欧美男人天堂网| 欧美高清一级片在线观看| 无罩大乳的熟妇正在播放| 久久精品福利| 性欧美长视频免费观看不卡| 丰满少妇被猛烈进入| 亚洲综合区在线| 五月天国产视频| 最新欧美人z0oozo0| 91中文在线视频| h片在线播放| 日韩精品一区二区三区在线| 久久久久97国产| 丁香激情综合五月| 九九爱精品视频| 欧美亚视频在线中文字幕免费| 97超级碰碰碰久久久| 欧美在线观看在线观看| 在线亚洲一区二区| 大地资源高清在线视频观看| 国产一区二区三区在线观看免费 | 亚洲成人看片| 中文字幕国产日韩| 国产精品玖玖玖| 一区二区在线观看av| 日本久久久久久久久久| 国产日韩精品视频一区二区三区 | 91精品成人| 亚洲影院色无极综合| 成年网站在线视频网站| 日韩风俗一区 二区| 成人毛片一区二区三区| 国产精品久久综合| 又黄又爽又色的视频| 亚洲视频二区| 亚洲伊人婷婷| 99亚洲乱人伦aⅴ精品| 91av免费观看91av精品在线| 国产系列在线观看| 在线综合亚洲欧美在线视频 | 色噜噜狠狠成人网p站| 国产一二三av| 成人午夜电影网站| 成人性视频欧美一区二区三区| 欧美gayvideo| 国产一级特黄a大片99| 日韩电影免费观| 另类视频在线观看| 青青操视频在线| 在线成人免费视频| 日本中文在线播放| 国产精品九色蝌蚪自拍| 真实乱偷全部视频| 久久久久国内| 国产精品va在线观看无码| 欧美人与牛zoz0性行为| 91亚洲va在线va天堂va国| 免费看男女www网站入口在线| 中文字幕欧美精品日韩中文字幕| 亚洲国产www| 欧美三级电影在线观看| 影音先锋亚洲天堂| 一区在线观看视频| 日韩乱码人妻无码中文字幕久久| 国产在线视视频有精品| 黑人糟蹋人妻hd中文字幕| 久久精品免费一区二区三区| 免费久久久一本精品久久区| 欧美精品影院| 国产精品久久久久久av下载红粉 | 亚洲成人av电影在线| 影音先锋男人资源在线观看| www激情久久| 国产av一区二区三区传媒| 乱一区二区av| 草草草在线视频| 在线看片一区| 日韩不卡一二区| 日韩中文欧美| 水蜜桃亚洲精品| 亚洲精品亚洲人成在线| 国产青春久久久国产毛片| 中文字幕久久精品一区二区| 成人动漫网站在线观看| 神马电影网我不卡| 91精品国产91久久久久久久久 | 国产精品久久久久久久久免费| 123区在线| 欧美二区在线播放| 国产原厂视频在线观看| 在线视频欧美日韩| 精品美女视频在线观看免费软件| 亚洲黄色www| 亚洲 小说区 图片区 都市| 欧美tk丨vk视频| 亚洲AV无码成人片在线观看| 91精品国产综合久久蜜臀| 在线免费看91| 欧美蜜桃一区二区三区| 亚洲综合免费视频| 欧美私人免费视频| 亚洲专区在线播放| 欧美日韩1234| 国产伦精品一区二区三区视频痴汉| 欧美日韩黄色一区二区| 在线免费观看av片| 欧美精品视频www在线观看| 国产一区二区三区中文字幕| 欧美日韩不卡在线| 国产探花精品一区二区| 日韩欧美三级在线| 亚洲成a人片在线| 亚洲成在人线av| 亚洲av毛片成人精品| 亚洲女人被黑人巨大进入| 你懂的在线观看视频网站| 亚洲人成网7777777国产| 免费在线黄色影片| 这里只有精品在线播放| 日本在线免费看| 欧美日韩福利在线观看| а√在线中文在线新版| 欧亚精品中文字幕| 78精品国产综合久久香蕉| 国产日韩欧美中文| 涩爱av色老久久精品偷偷鲁 | 九一在线视频| 中文字幕亚洲欧美一区二区三区 | 最近高清中文在线字幕在线观看| 中文字幕一区电影| 中文在线字幕免费观看| 久久久久久91香蕉国产| 亚洲黄色免费看| 国产精品日本精品| 91亚洲无吗| 欧美日韩三区四区| 婷婷丁香综合| 性欧美大战久久久久久久| 日韩专区一卡二卡| 四虎成人在线播放| 99久久综合国产精品| 亚洲а∨天堂久久精品2021| 18成人在线视频| 日本一二三区不卡| 欧美三级资源在线| 亚洲黄色在线免费观看| 亚洲高清一二三区| 酒色婷婷桃色成人免费av网| 久久天天躁狠狠躁夜夜av| 国产美女高潮在线| 成人xvideos免费视频| 色婷婷久久久| 特级毛片在线免费观看| 亚洲综合精品| 色欲无码人妻久久精品| 久久久亚洲午夜电影| www.毛片com| 色视频成人在线观看免| 国产成人精品白浆久久69| 国产亚洲精品久久久久久| 神马午夜伦理不卡 | 日本一区二区三区在线观看| 欧美日韩激情在线观看| 日韩欧美国产高清91| 国产又大又长又粗| 日韩av最新在线观看| а√天堂官网中文在线| 国产成人精品视频| 麻豆一区二区| 男女激烈动态图| 青青青伊人色综合久久| 亚洲第九十七页| 一区二区三区四区不卡在线| 在线观看你懂的网站| 精品va天堂亚洲国产| 爆操欧美美女| 国产精品入口日韩视频大尺度| 日韩激情网站| 国产妇女馒头高清泬20p多| 国模大尺度一区二区三区| 一级黄色录像毛片| 欧美性猛交xxxx富婆弯腰| 亚洲欧美黄色片| 欧美成人免费大片| 欧洲精品久久久久毛片完整版| 欧美日韩国产一二| 妖精视频成人观看www| 精品久久久久一区二区| 亚洲综合免费观看高清完整版在线| 国产精品久久久久毛片| 日日噜噜噜夜夜爽亚洲精品| 日韩影片中文字幕| 欧美污视频久久久| 亚洲中字黄色| 波多野结衣 在线| 黑人巨大精品欧美一区二区一视频 | 2021天堂中文幕一二区在线观| 147欧美人体大胆444| 亚洲电影影音先锋| 亚洲欧美天堂在线| 亚洲欧美在线视频观看| 一级片在线观看视频| 最近2019年日本中文免费字幕| 国产激情欧美| 中文字幕一区二区三区在线乱码 | 国产精品中文字幕在线| 国产探花一区| 手机看片福利日韩| 国产精品色哟哟| 91片黄在线观看喷潮| 久久精品国产亚洲7777| 国产精品亚洲一区二区在线观看| 青青草影院在线观看| 国产成人av电影在线| 国产午夜视频在线播放| 亚洲精品按摩视频| 亚洲wwww| 一区二区三区视频| 国产一区二区在线视频| 九九热这里有精品视频| 亚洲成人精品视频在线观看| 精品丝袜在线| 欧美精品尤物在线| 麻豆精品在线看| 麻豆明星ai换脸视频| 精品国产一区二区精华| 看黄在线观看| 日韩一区不卡| 国产一区二区三区在线观看免费 | 激情国产一区二区| 久久99久久久| 亚洲女同精品视频| 欧美天堂一区二区| www.在线观看av| 久久亚洲一区二区三区四区| 中文字幕在线播放不卡| 久久97久久97精品免视看| 免费成人三级| 亚洲娇小娇小娇小| 一区二区视频在线| 色视频在线观看福利| 国产精品自产拍在线观看| 欧美成人嫩草网站| 熟女少妇一区二区三区| 91精品国产色综合久久不卡电影| h片精品在线观看| 色一情一乱一伦一区二区三欧美| 国产在线精品一区二区| 国产精品视频久久久久久久| 色偷偷9999www| 青青久久av| 污污视频在线免费| 欧美性猛交xxxx偷拍洗澡| 麻豆tv在线| 久久久久久久久一区| 国产一区日韩二区欧美三区| 91video| 九色91av视频| 成人av二区| 亚洲成人精品在线播放| 在线免费观看不卡av|