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

FastDFS并發會有bug,其實我也不太信?- 一次并發問題的排查經歷

開發 開發工具
前一段時間,業務部門同事反饋在一次生產服務器升級之后,POS消費上傳小票業務偶現異常,上傳小票業務有重試機制,有些重試三次也不會成功,他們排查了一下沒有找到原因,希望架構部幫忙解決。

前一段時間,業務部門同事反饋在一次生產服務器升級之后,POS消費上傳小票業務偶現異常,上傳小票業務有重試機制,有些重試三次也不會成功,他們排查了一下沒有找到原因,希望架構部幫忙解決。

公司使用的是FastDFS來做的圖片服務器,生產使用了六臺服務器外加一個存儲,集群采用的是:2個tracker+4個storage,storage分為兩個group,使用獨立的nginx做文件代理訪問。各軟件版本信息如下:

  • 操作系統:centos6.9
  • FastDFS :5.05
  • libfastcommon:1.0.36
  • nginx :1.7.9
  • fastdfs-nginx-module:1.16

為了盡可能的模擬生產,我在測試環境1:1搭建了一套和生產一樣的FastDFS集群,當時也寫了搭建過程:FastDFS 集群 安裝 配置

從日志中找線索

業務部門同事反饋,在一次生產服務器升級之后,重新搭建了一套FastDFS集群,然后過了幾天就開始出現上傳小票偶爾失敗的問題。根據這些信息的反饋,我懷疑是否是FastDFS搭建有問題?這個懷疑點差點把我帶到溝里去。

我拉取了FastDFS的日志,tracker服務器日志如下:

  1. [2017-09-19 09:13:52] ERROR - file: tracker_nio.c, line: 306, client ip: 192.168.0.1, pkg length: 15150 > max pkg size: 8192 
  2. [2017-09-19 10:34:57] ERROR - file: tracker_nio.c, line: 306, client ip: 192.168.0.1, pkg length: 16843 > max pkg size: 8192 
  3. [2017-09-19 10:34:57] ERROR - file: tracker_nio.c, line: 306, client ip: 192.168.0.1, pkg length: 16843 > max pkg size: 8192 
  4. [2017-09-19 11:31:08] ERROR - file: tracker_nio.c, line: 306, client ip: 192.168.03, pkg length: 23955 > max pkg size: 8192 
  5. [2017-09-19 11:42:56] ERROR - file: tracker_nio.c, line: 306, client ip: 192.168.01, pkg length: 12284 > max pkg size: 8192 
  6. [2017-09-19 12:10:28] ERROR - file: tracker_service.c, line: 2452, cmd=103, client ip: 192.168.0.3, package size 6258 is too long, exceeds 144 

根據tracker的日志信息可以看出,不時有一些小票文件的大小大于最大傳輸值8192,跟著這個線索順著上傳的那條線進行了排查,比如nginx上傳大小的限制,tracker上傳大小的限制,是不是生成的小票出現異常,大小突然變大。麻溜的整了半天得出結論,上傳小票失敗和這個異常沒有關系。

接下來看了下storaged的日志:

  1. [2017-09-25 14:22:38] WARNING - file: storage_service.c, line: 7135, client ip: 192.168.1.11, logic file: M00/D1/04/wKg5ZlnIoKWAAkNRAAAY86__WXA920.jpg-m not exist 
  2. [2017-09-25 14:22:39] WARNING - file: storage_service.c, line: 7135, client ip: 192.168.1.11, logic file: M00/D1/04/wKg5ZlnIoKuAUXeVAAAeASIvHGw673.jpg not exist 
  3. [2017-09-25 14:22:50] ERROR - file: storage_nio.c, line: 475, client ip: 192.168.1.13, recv failed, errno: 104, error info: Connection reset by peer 
  4. [2017-09-25 14:22:56] ERROR - file: tracker_proto.c, line: 48, server: 192.168.1.11:23001, response status 2 != 0 
  5. [2017-09-25 14:23:06] ERROR - file: tracker_proto.c, line: 48, server: 192.168.1.11:23001, response status 2 != 0 
  6. [2017-09-25 14:23:11] ERROR - file: storage_service.c, line: 3287, client ip:192.168.1.13, group_name: group2 not correct, should be: group1 

除了看到一些文件不存在的警告和響應狀態不對的錯誤外,也沒有發現其它的異常。

最后來看應用中的錯誤日志,其中有兩段錯誤日志引起了我的注意:

第一段日志如下:

  1. org.csource.common.MyException: body length: 0 <= 16 
  2.    at org.csource.fastdfs.StorageClient.do_upload_file(StorageClient.java:799) 
  3.    at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:208) 
  4.    at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:226) 
  5.    at com.xxx.neo.fastdfs.FileManager.upload(FileManager.java:86) 
  6.    at com.xxx.neo.controller.QpayUploadSignController.saveSign(QpayUploadSignController.java:84) 
  7.    at com.xxx.neo.controller.QpayUploadSignController.uploadSign(QpayUploadSignController.java:65) 
  8.    at com.xxx.neo.controller.QpayUploadSignController$$FastClassByCGLIB$$5debf81b.invoke(<generated>) 
  9.    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 
  10.    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689) 
  11.    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 

跟了一下fastdfs-client-java中的源碼的douploadfile方法,有這么一段:

  1. ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(storageSocket.getInputStream(), 
  2.              ProtoCommon.STORAGE_PROTO_CMD_RESP, -1); 
  3. //省略中間代碼               
  4. if (pkgInfo.body.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) { 
  5.    throw new MyException("body length: " + pkgInfo.body.length + " <= " + ProtoCommon.FDFS_GROUP_NAME_MAX_LEN); 
  6.  } 

pkgInfo是封裝好的文件流信息,ProtoCommon是fastdfs-client-java中封裝好的參數類,其中FDFSGROUPNAMEMAXLEN的值為16,代碼的意思就是當讀取的大小小于16字節的時候,拋出MyException異常。

第二段日志如下:

  1. [ INFO] [http://*:8083-69096 2017-09-25 14:07:32] (FileManager.java:upload:92) upload_file time used:76 ms 
  2. [ INFO] [http://*:8083-69096 2017-09-25 14:07:32] (FileManager.java:upload:103) upload file successfully!!!group_name:group2, remoteFileName: M00/3C/A8/wKg5Z1nInSOAaHSNAAAdNipAyrQ611.jpg 
  3. upload file successfully!!!group_name:group2, remoteFileName: M00/3C/A8/wKg5Z1nInSOAaHSNAAAdNipAyrQ611.jpg 
  4. [Ljava.lang.String;@17584701 
  5. [ERROR] [http://*:8083-69087 2017-09-25 14:07:32] (FileManager.java:upload:90) Non IO Exception when uploadind the file:520 
  6. java.lang.NullPointerException 
  7.    at org.csource.fastdfs.StorageClient.do_upload_file(StorageClient.java:842) 
  8.    at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:208) 
  9.    at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:226) 
  10.    at com.xxx.neo.fastdfs.FileManager.upload(FileManager.java:86) 
  11.    at com.xxx.neo.controller.QpayUploadSignController.saveSign(QpayUploadSignController.java:84) 
  12.    at com.xxx.neo.controller.QpayUploadSignController.uploadSign(QpayUploadSignController.java:65) 
  13.    at com.xxx.neo.controller.QpayUploadSignController$$FastClassByCGLIB$$5debf81b.invoke(<generated>) 
  14.    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 
  15.    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689) 

日志中關于空指針的異常最多,跟蹤了fastdfs-client-java的源碼,空指針都出現在以下幾段代碼:

第一處:

  1. ... 
  2. storageSocket = this.storageServer.getSocket(); 
  3. ext_name_bs = new byte[ProtoCommon.FDFS_FILE_EXT_NAME_MAX_LEN]; 
  4. Arrays.fill(ext_name_bs, (byte) 0); 
  5. ... 
  6. ​ 

第二處:

  1. if (!bNewConnection) { 
  2.    try { 
  3.      this.storageServer.close(); 
  4.    } catch (IOException ex1) { 
  5.      ex1.printStackTrace(); 
  6.    } finally { 
  7.      this.storageServer = null

第三處:

  1. if (bNewConnection) { 
  2.    try { 
  3.      this.storageServer.close(); 
  4.    } catch (IOException ex1) { 
  5.      ex1.printStackTrace(); 
  6.    } finally { 
  7.      this.storageServer = null
  8.    } 
  9.  } 

大家有沒有發現這三段代碼都有一個共同之處?就是存在storageServer變量的使用,并且在調用的地方出現了空指針異常,難道fastdfs-client-java有bug?覺得不太可能,畢竟那么多人使用,會不會是我們使用的版本太舊或者使用方式不對呢?

日志中的IP地址和公司信息均已進行脫敏

FastDFS提供的Jar包有問題?

帶著上面的懷疑我準備搞個多線程壓測一下,看是不是并發的時候產生的問題。使用CountDownLatch讓線程集中執行,代碼如下:

  1. private static void latchTest() throws InterruptedException { 
  2.        final CountDownLatch start = new CountDownLatch(1); 
  3.        final CountDownLatch end = new CountDownLatch(poolSize); 
  4.        ExecutorService exce = Executors.newFixedThreadPool(poolSize); 
  5.        for (int i = 0; i < poolSize; i++) { 
  6.            Runnable run = new Runnable() { 
  7.                @Override 
  8.                public void run() { 
  9.                    try { 
  10.                        start.await(); 
  11.                        testLoad(); 
  12.                    } catch (InterruptedException e) { 
  13.                        e.printStackTrace(); 
  14.                    } finally { 
  15.                        end.countDown(); 
  16.                    } 
  17.                } 
  18.            }; 
  19.            exce.submit(run); 
  20.        } 
  21.        start.countDown(); 
  22.        end.await(); 
  23.        exce.shutdown(); 
  24.    } 

CountDownLatch是Java多線程同步器的四大金剛之一,CountDownLatch能夠使一個線程等待其他線程完成各自的工作后再執行。

使用Executors.newFixedThreadPool創建固定大小的線程池,剛開始設置的是12,每個線程執行一萬次上傳請求。

  1. public static void testLoad() { 
  2.    String filePath="C:\\Users\\xxx\\Pictures\\xz.jpg"
  3.    File file=new File(filePath); 
  4.    String serverUrl="http://localhost:8080/uploadSign"
  5.    for (int i=0;i<10000;i++){ 
  6.        HttpClientUtils.uploadFile(file,serverUrl); 
  7.    } 

Controller層接到請求后,組裝FastDFSFile進行上傳

  1. .... 
  2. byte[] file_buff = null
  3.    if(inputStream!=null){ 
  4.        int len1 = inputStream.available(); 
  5.        file_buff = new byte[len1]; 
  6.        inputStream.read(file_buff); 
  7.    } 
  8. FastDFSFile file = new FastDFSFile("520", file_buff, "jpg"); 
  9. try { 
  10.     fileAbsolutePath = FileManager.upload(file);  //上傳到分布式文件系統 
  11.    System.out.println(fileAbsolutePath); 
  12. } catch (Exception e1) { 
  13.    e1.printStackTrace(); 
  14. ... 

再進行一些封裝之后,最終調用fastdfs-client-java的 upload_file()方法

  1. .... 
  2. uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list); 
  3. .... 
  4. ​ 

壓測代碼寫完之后,迫不及待的運行了起來,準備驗證一把,結果非常出意料,剛一啟動就不斷的報空指針異常,看到這個空指針異常我卻一陣歡喜,這個異常和我在生產看到的異常一模一樣。平時最棘手的問題,就是生產偶現測試環境又不能復現的問題,很難定位異常的原因,一旦可以在測試環境復現問題,那就意味著問題解決了一半。

接下來,我將線程池的個數減少到6個,啟動測試后還是狂報異常;接著將線程數減到2個,每個線程數執行的數量由以前的10000改為100個,修改后再進行測試還是報錯;沒辦法改成一個線程來運行,果然程序可以正常上傳小票了,確認是并發導致的問題。

這樣可以得出預判,在業務高峰期間產生并發導致部分小票上傳業務失敗,那為什么這個問題一直沒有發現呢?有兩方面的因素:第一,可能業務初期并發量并不是很高,上傳小票也不是主干業務,偶爾出現一兩筆失敗也有重試機制來后補;第二,生產環境使用了六臺服務器做負載,請求被均勻分發到六臺服務器中,在某種程度上也避免了單臺服務器的并發量,只有業務并發量進一步擴大才出現明顯的異常。

嘗試著去解決

既然異常都發生在upload_file方法storageServer出現的地方,那么我們就研究研究這個storageServer是個什么鬼?storageServer根據屬性名可以看出來,storageServer是上傳文件的storage存儲節點,每次上傳文件的時候從trackerServer中獲取。

跟蹤源碼可以發現,storageServer會在兩個地方進行初始化:第一,在初始化storageClient的時候

  1. storageClient = new StorageClient(trackerServer, storageServer);​ 

這里的storageServer可以為空;如果為空會自動從trackerServer中獲取,如果需要指定具體的storage可以在這里進行初始化。

第二,在調用 do_upload_file()方法開頭中,下面代碼截取于 do_upload_file()方法。

  1. bUploadSlave = ((group_name != null && group_name.length() > 0) && 
  2.        (master_filename != null && master_filename.length() > 0) && 
  3.        (prefix_name != null)); 
  4. if (bUploadSlave) { 
  5.  bNewConnection = this.newUpdatableStorageConnection(group_name, master_filename); 
  6. else { 
  7.  bNewConnection = this.newWritableStorageConnection(group_name); 
  8. try { 
  9.  storageSocket = this.storageServer.getSocket(); 
  10. ... 

在 do_upload_file()方法的開頭,會根據條件運行 this.newUpdatableStorageConnection(group_name,master_filename)方法或者 this.newWritableStorageConnection(group_name)方法,在這兩個方法中都會有對storageServer進行初始化。我們來看 newWritableStorageConnection(group_name)方法的源碼:

  1. /** 
  2. check storage socket, if null create a new connection 
  3. * @param group_name the group name to upload file to, can be empty 
  4. * @return true if create a new connection 
  5. */ 
  6. protected boolean newWritableStorageConnection(String group_name) throws IOException, MyException { 
  7. if (this.storageServer != null) { 
  8.  return false
  9. else { 
  10.  TrackerClient tracker = new TrackerClient(); 
  11.  this.storageServer = tracker.getStoreStorage(this.trackerServer, group_name); 
  12.  if (this.storageServer == null) { 
  13.    throw new MyException("getStoreStorage fail, errno code: " + tracker.getErrorCode()); 
  14.  } 
  15.  return true

這個方法比較簡單,首先判斷storageServer是否進行過初始化,如果沒有初始化,則從tracker中獲取一個可用的storageServer進行初始化。初始化之后douploadfile()方法會根據拿到的storageServer進行文件上傳操作。

接下來到了全文最關鍵的地方的了,douploadfile()方法會在上傳文件結束的時候,將storageServer關閉并賦值為空,相關代碼如下:

  1. } catch (IOException ex) { 
  2.  if (!bNewConnection) { 
  3.    try { 
  4.      this.storageServer.close(); 
  5.    } catch (IOException ex1) { 
  6.      ex1.printStackTrace(); 
  7.    } finally { 
  8.      this.storageServer = null
  9.    } 
  10.  } 
  11.  throw ex; 
  12. } finally { 
  13.  if (bNewConnection) { 
  14.    try { 
  15.      this.storageServer.close(); 
  16.    } catch (IOException ex1) { 
  17.      ex1.printStackTrace(); 
  18.    } finally { 
  19.      this.storageServer = null
  20.    } 
  21.  } 

當然這個邏輯是沒有問題的,每次方法執行的時候獲取一個可用的storageServer,結束的時候進行回收,避免多次請求使用同一個storage。如果程序沒有任何并發這段代碼是沒有問題的,如果出現并發呢,出現小的并發也不一定會出現問題,當并發量稍微大一點的時候就一定會出現問題,這是為什么呢?

我們來繼續跟蹤storageServer,發現storageServer是StorageClient類的一個全局屬性,當并發特別大的時候就有可能出現這樣一個現象:第一個線程進這個方法的時候,看到storageServer沒有初始化于是進行賦值并繼續往下執行;這時候第二個線程又開始進入這個方法,發現storageServer已經進行了初始化,就不再初始化,繼續往下執行;當第一個線程執行結束的時候,將storageServer關閉并賦值為null,然后拍屁股走人了;這個時候可苦逼第二個線程了,方法剛剛執行了一半,當需要使用storageServer的時候,才發現storageServer已經被置為了null,于是在使用storageServer的地方都有可能會出現空指針異常,第二個線程,在掛掉的時候一定在想,真XX的坑爹。

于是上面的這個故事,過一段時間就偷偷的在我們生產環境中上演。

后面我繼續看了一下StorageClient源碼,不但是douploadfile()會存在此問題,StorageClient類中只要這樣使用storageServer的地方都會出現類似的并發問題,如:domodifyfile方法、delete_file方法等等。

那么既然找到了問題的根因,到底如何解決這個問題呢?解決這個問題的本質就是解決共享變量的并發問題,那解決共享變量并發有哪些手段呢?最常用有加鎖或者使用Threadlocal,看了一下使用Threadlocal進行改造工作量比較大,因此我最后選擇使用了Synchronized同步鎖來解決這個問題,就是在每個使用storageServer方法上面添加一個Synchronized關鍵字。

  1. protected Synchronized  String[] do_upload_file()​ 

在github上面將源碼down下來 fastdfs-client-java,修改完之后再進行壓測,妥妥的再不會報空指針異常類了。

峰回路轉

大家以為這樣就結束了嗎?當時我也是這樣認為的。后來回頭一想,這樣雖然解決了問題,但是并發數卻急劇降低,FastDFS不會這么傻吧!肯定還是自己出了問題,第二天將項目中FastDFS使用的代碼又擼了一遍,果然發現問題了。

FileManager是我們封裝好的FastDFS工具類,在啟動的時候會對storageClient進行初始化,這樣每次項目調研的時候都會復用storageClient實例。

  1. public class FileManager implements FileManagerConfig { 
  2.  private static StorageClient storageClient; 
  3.  static { 
  4.      try { 
  5.      //省略一部分代碼 
  6.      trackerClient = new TrackerClient(); 
  7.      trackerServer = trackerClient.getConnection(); 
  8.      storageClient = new StorageClient(trackerServer, storageServer); 
  9.    } catch (Exception e) { 
  10.      logger.error(e); 
  11.    } 
  12.  } 

upload()方法每次會從全局變量中獲取storageClient進行調用,也就意味著每次請求使用的是同一個storageClient實例,當然也包括實例中的變量storageServer。

  1. public static String[] upload(FastDFSFile file) { 
  2.    try { 
  3.      uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list); 
  4.    } catch (Exception e) { 
  5.      logger.error("Exception when uploadind the file:" + file.getName(), e); 
  6.    } 
  7.    //省略一部分代碼 
  8.    return uploadResults; 
  9.  } 

如果我將上面的 upload()方法改造成下面這樣呢:

  1. public static String[] upload(FastDFSFile file) { 
  2.    try { 
  3.      StorageClient  storageClient = new StorageClient(trackerServer, storageServer); 
  4.      uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list); 
  5.    } catch (Exception e) { 
  6.      logger.error("Exception when uploadind the file:" + file.getName(), e); 
  7.    } 
  8.    //省略一部分代碼 
  9.    return uploadResults; 
  10.  } 
  11. ​ 

重點是添加了這段代碼: StorageClientstorageClient=newStorageClient(trackerServer,storageServer);

也就是說,每次調用的時候會重新new一個StorageClient()實例,這樣每次請求拿到的就是不同的StorageClient,也就意味著每個請求會獲取到不同的storageServer,這樣就不存在共享變量,也就避免了出現并發的空指針問題。

根據上面的分析可以看出,最好的解決方案就是每次調用的時候new一個新的實例去使用。也提醒大家在使用FastDFS的時候,盡量不要重用StorageClient!

后來我在github上面給FastDFS提交了pull來說明這個問題,有一個網友也給出了同樣的理解:解決并發空指針問題 (https://github.com/happyfish100/fastdfs-client-java/pull/28);文中的測試代碼我放到了這里:(https://github.com/ityouknow/spring-examples),感興趣的同學可以繼續去了解。

最后

問題終于解決了,雖然走了彎路,卻讓我對FastDFS有了更深的認識。平時解決問題也經常會這樣,有時候排查了整整一天,才發現原來是某個非常低級錯誤導致的,這就是程序員的正常工作。其實淘寶也有一個版本的FastDFS客戶端,地址在這里(https://github.com/tobato/FastDFS_Client)。并且提供了更多的功能支持,比如斷點續傳、連接池等,推薦大家使用這個版本。

研究發現,在所有報告的錯誤中,大約有95%是由程序員造成的,2%是由系統軟件(編譯器和操作系統)造成的,2%是由其他軟件造成的,1%是由硬件造成的。因此不要懷疑人生、出現什么奇跡、發生某些詭異的事情,那是不會發生的。

要相信編程的第一法則:永遠都是你的錯!

你應該知道那種感覺。我們所有人都曾碰到過這樣的事情:已經盯著代碼看了無數遍,但還是沒有發現任何問題。然而,有個故障或者錯誤始終揮之不去。于是你開始懷疑,可能是你開發程序所用的那臺機器出了問題,也可能是操作系統的問題,或者是你使用的工具和庫出了問題。肯定是它們的原因!

然而,無論你多么絕望,都不要往那條路上走。沿著那條路下去就是薛定諤的貓和靠運氣編程。

總是要處理一些困難的、捉摸不透的問題,這是一件令人絕望的事情,但是不要讓絕望領著你誤入歧途。作為一名謙遜的程序員,最基本的要求就是要有意識:你寫的代碼在任何時候出了問題,那一定都是你的錯。

【本文為51CTO專欄作者“純潔的微笑”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

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

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2025-03-17 10:01:07

2022-07-13 08:31:18

React問題排查

2013-04-01 10:27:37

程序員失業

2023-10-23 08:12:34

并發問題有鎖和無鎖

2022-09-07 09:09:13

高并發架構

2012-02-02 15:57:09

HibernateJava

2009-11-25 13:33:39

并發

2022-09-13 13:49:05

數據庫隔離

2012-07-12 14:35:31

面試經歷

2021-05-13 08:51:20

GC問題排查

2023-04-06 07:53:56

Redis連接問題K8s

2012-08-28 09:21:59

Ajax查錯經歷Web

2022-11-03 16:10:29

groovyfullGC

2020-10-27 10:35:38

優化代碼項目

2021-11-23 21:21:07

線上排查服務

2023-03-29 09:36:32

2021-12-06 19:29:17

LRU內存算法

2021-05-31 10:08:44

工具腳本主機

2021-03-29 12:35:04

Kubernetes環境TCP

2021-07-01 19:31:50

并發JavaCPU
點贊
收藏

51CTO技術棧公眾號

天天做综合网| 欧美性video| 久久99精品国产91久久来源| 久久久www成人免费精品张筱雨| 伊人国产精品视频| 国产探花视频在线观看| 国产性色一区二区| 99国产视频| 久草视频一区二区| 中文字幕av亚洲精品一部二部| 精品国产91洋老外米糕| 一区二区在线播放视频| 中文字幕在线播放网址| 久久久久国产精品人| 91超碰在线电影| 你懂的国产在线| 欧美黄在线观看| 中文字幕精品国产| 欧美肉大捧一进一出免费视频| 激情小说亚洲| 欧美午夜宅男影院在线观看| 在线观看日本一区| 嫩草精品影院| 成人激情免费网站| 亚洲va久久久噜噜噜| 91精品国产高清一区二区三密臀| 午夜视频精品| 日韩在线视频观看正片免费网站| 噜噜噜在线视频| 欧美欧美在线| 欧美电影影音先锋| 黄色三级视频片| 中文字幕在线中文字幕在线中三区| 日韩美女啊v在线免费观看| 久久综合九色99| 亚洲精品第五页| 国产一区二区伦理片| 国产精品久久久久久久av大片| 日韩欧美大片在线观看| 欧美三级黄美女| 日韩亚洲欧美中文在线| 日本二区在线观看| 中国av一区| 日韩高清免费在线| 日本性生活一级片| 深夜福利一区| 日韩精品一区二区在线| 亚洲色图欧美自拍| 警花av一区二区三区| 欧美顶级少妇做爰| 一级黄色片在线免费观看| 国产精品久久久久久妇女| 日韩欧美中文第一页| 男女高潮又爽又黄又无遮挡| a毛片不卡免费看片| 亚洲国产一区二区三区青草影视| 成人短视频在线观看免费| av在线播放国产| 亚洲黄色尤物视频| 国产精品视频一二三四区| 色呦呦在线观看视频| 樱花影视一区二区| 久久久久久久9| freexxx性亚洲精品| 天天综合色天天综合| 久色视频在线播放| 暖暖成人免费视频| 欧美在线一区二区| 红桃视频 国产| 日韩中文字幕在线一区| 欧美精品一区二区在线观看| 日韩免费高清一区二区| 国产精品密蕾丝视频下载 | 另类图片亚洲另类| 国内偷拍精品视频| 亚洲欧洲午夜| 国产精品99久久久久久www| 中文字幕在线网站| 国内外成人在线| 成人动漫在线视频| 日韩电影免费| 中文字幕一区二区视频| 波多野结衣 作品| 国产va在线视频| 在线视频欧美精品| 激情文学亚洲色图| 国产乱人伦丫前精品视频| 亚洲欧美福利视频| 大地资源高清在线视频观看| 亚洲第一毛片| 国产精品视频一| 懂色av蜜臀av粉嫩av分享吧| 久久久精品黄色| 在线观看av的网址| 日韩欧美另类一区二区| 欧美一区二区啪啪| 亚洲午夜福利在线观看| 亚洲成人av| 奇米4444一区二区三区| 97超视频在线观看| 91亚洲午夜精品久久久久久| 日本特级黄色大片| 成人欧美大片| 精品欧美乱码久久久久久1区2区| 亚洲人成人无码网www国产| 自拍视频亚洲| 国产精品精品久久久久久| 性一交一乱一精一晶| 久久精品在线免费观看| www污在线观看| 日本精品久久| 亚洲欧美在线磁力| 国产一级特黄毛片| 蜜臀av一区二区| 久久久久久99| 先锋成人av| 欧美日韩日本视频| 精品中文字幕在线播放| 牛夜精品久久久久久久99黑人| 国产99在线|中文| 人成网站在线观看| 中文字幕佐山爱一区二区免费| 欧美成人精品欧美一级乱| 97色成人综合网站| 久久视频免费观看| 中文字幕在线日亚洲9| 久久免费的精品国产v∧| 妺妺窝人体色777777| 国产麻豆一区二区三区| 色999日韩欧美国产| 黄色片视频免费| 91在线视频网址| 99在线免费视频观看| 精品一区91| 精品国产自在精品国产浪潮| 国产精品sm调教免费专区| 久久综合视频网| 国产免费毛卡片| 精品亚洲自拍| 国语对白做受69| 亚洲国产精品久久久久久6q| 亚洲欧美日韩国产中文在线| 亚洲欧美另类动漫| 成人直播大秀| 国产日韩亚洲欧美| 日本最黄一级片免费在线| 欧美三级电影网| 波多野结衣家庭教师在线观看| 日本成人中文字幕在线视频| 日韩精品久久久毛片一区二区| 日本韩国欧美| 国产一区二区三区视频免费| 超碰在线观看91| 日本一区二区成人| 日韩欧美国产片| 外国成人激情视频| 69堂成人精品视频免费| 特级毛片在线| 欧美精品一区二区在线观看| 国产午夜在线播放| 91色综合久久久久婷婷| 国产成人久久777777| brazzers精品成人一区| 亚洲精品免费av| 国产精品成人无码专区| 91成人精品| 97自拍视频| av老司机免费在线| 日韩电影中文字幕在线| 亚洲大片免费观看| 国产精品乱码人人做人人爱 | 日本中文字幕一区二区视频 | 日本激情在线观看| 欧美日韩视频不卡| 欧美精品乱码视频一二专区| 成人一区在线看| 欧美牲交a欧美牲交| 国产欧美日韩精品一区二区三区| 国产精品永久免费观看| 在线免费观看污| 日韩av在线网站| 嫩草影院一区二区三区| 一区二区三区免费观看视频| 天天操中文字幕| 西西44rtwww国产精品| 国产精品第9页| 欧美1区2区3区4区| 81精品国产乱码久久久久久| 欧美精品a∨在线观看不卡 | 国产老肥熟一区二区三区| 国产精品久久久久久久久电影网| 欧洲在线一区| 国产综合久久久久| 欧美在线极品| 久久精品国产免费观看| 天天av综合网| 91精品国产91综合久久蜜臀| 性无码专区无码| **欧美大码日韩| 日本丰满少妇裸体自慰| 精品一区二区三区欧美| 国产精品久久中文字幕| 久久国产亚洲| 精品乱码一区| 国产精久久一区二区| 日本精品一区二区三区在线| aa在线视频| 在线看日韩av| 天堂在线视频观看| 日韩欧美另类在线| 中文字幕乱码中文字幕| 亚欧色一区w666天堂| 日韩在线视频免费看| 久久综合久久鬼色| 欧美午夜精品一区二区| 蜜臀av性久久久久av蜜臀妖精| 黄色片网址在线观看| 亚洲国产一区二区在线观看| 美乳视频一区二区| 激情视频极品美女日韩| 91精品视频大全| 成人黄色视屏网站| 热99久久精品| 色偷偷偷在线视频播放 | 亚洲女同av| 欧美精品电影在线| 国产区在线观看| 中文字幕在线日韩| 国产一区电影| 亚洲欧美三级伦理| 日韩a在线看| 亚洲国产精品久久久久| 丰满人妻av一区二区三区| 538prom精品视频线放| 中文字幕一区二区三区人妻四季| 一本久道中文字幕精品亚洲嫩| 日本学生初尝黑人巨免费视频| 亚洲免费在线电影| 翔田千里88av中文字幕| 1000精品久久久久久久久| 手机看片福利视频| 欧美国产视频在线| 免费看日本黄色片| 国产女同互慰高潮91漫画| 熟女高潮一区二区三区| 久久久午夜精品| 在线观看福利片| 国产午夜亚洲精品不卡| 亚洲精品国产一区黑色丝袜| 久久久不卡网国产精品二区| av在线网站观看| 久久精品人人做人人综合| 波多野吉衣中文字幕| 国产三级欧美三级日产三级99 | 亚洲品质自拍视频| 国内偷拍精品视频| 亚洲成人av电影| 中文字幕在线观看免费视频| 欧美日韩中文在线观看| 精品国产乱子伦| 欧美最猛黑人xxxxx猛交| 中文字幕+乱码+中文乱码www| 欧美日韩一区二区在线视频| 国产精品久久久久久久久久久久久久久久 | 欧美www视频在线观看| 国产一区一区三区| 激情丁香综合| 久久久久久久激情| 日韩av中文在线观看| 一级黄色在线播放| 粉嫩一区二区三区性色av| 在线观看国产三级| 欧美韩日一区二区三区| 欧美激情精品久久久久久免费 | 中文字幕第四页| 日本丶国产丶欧美色综合| 在线免费av片| 欧美mv日韩mv| 黑人与亚洲人色ⅹvideos| 日韩一区二区精品视频| 欧美aaaxxxx做受视频| 欧美在线观看一区二区三区| 国产成人a视频高清在线观看| 91免费人成网站在线观看18| 国产精品久av福利在线观看| 日韩av高清在线播放| 午夜精品久久99蜜桃的功能介绍| 国产一区 在线播放| 国内久久精品| 国产精品久久久毛片| 国产成人在线视频网站| 精品一区二区三区四区五区六区| 国产欧美一区二区精品忘忧草| 激情综合五月网| 欧美性大战久久久| 人妻91麻豆一区二区三区| 一本色道久久综合狠狠躁篇的优点| av在线导航| 国产成人亚洲精品| 91综合久久爱com| 亚洲综合av一区| 国产精品一国产精品k频道56| 看看黄色一级片| 久久久久久久av麻豆果冻| 在线免费日韩av| 天天做天天摸天天爽国产一区| 国产露脸无套对白在线播放| 日韩国产精品视频| 日本在线视频中文有码| 国产精品久久久999| 日韩欧美国产大片| youjizz.com在线观看| 麻豆成人久久精品二区三区红| 日本少妇毛茸茸| 一区二区三区在线免费| 精品乱码一区内射人妻无码| 亚洲国产精品视频在线观看| 免费在线观看黄色| 国产成人拍精品视频午夜网站| 女仆av观看一区| 日本大胆人体视频| 久久99热这里只有精品| 一级黄色性视频| 欧美日韩久久久久| 老牛影视av牛牛影视av| 美女扒开尿口让男人操亚洲视频网站| 成人精品三级| 欧美性bbwbbwbbwhd| 国产欧美日韩一级| 制服丝袜第一页在线观看| 亚洲综合久久久| 国内精品偷拍视频| 久久成人亚洲精品| 999色成人| 日本黄色播放器| 麻豆精品视频在线观看| 中文字幕黄色网址| 在线视频你懂得一区| 国产区视频在线播放| 欧美洲成人男女午夜视频| 日韩欧美四区| heyzo国产| 久久久久国色av免费看影院| caoporn国产| 国产亚洲精品久久久久久| 97se综合| 色之综合天天综合色天天棕色| 久久久久国产精品一区三寸| 美女100%无挡| 91福利国产成人精品照片| eeuss影院www在线观看| 国产精品男人的天堂| 欧美jizz| 免费一区二区三区在在线视频| 中文字幕福利视频| 亚洲成人免费电影| 手机在线观看毛片| 91精品国产乱码久久久久久蜜臀| 国语一区二区三区| 久久成人免费观看| 久久久久成人黄色影片| 精品乱码一区内射人妻无码| 日韩亚洲欧美中文高清在线| 免费一级欧美在线大片| 人人妻人人澡人人爽欧美一区双| a亚洲天堂av| 九九热最新视频| 久久久国产一区| 97se亚洲国产一区二区三区| 亚洲熟妇av一区二区三区漫画| 国产午夜三级一区二区三| 一区二区三区免费在线| 裸体女人亚洲精品一区| 国产精品宾馆| 麻豆av免费在线| 1024国产精品| 香蕉视频黄在线观看| 国产精品wwww| 午夜精品久久99蜜桃的功能介绍| 少妇饥渴放荡91麻豆| 欧美日韩在线三区| 搞黄网站在线看| 日韩中文字幕av在线| 国产专区欧美精品| 天天操天天爽天天干| 久久韩剧网电视剧| 婷婷综合电影| 亚洲最大天堂网| 午夜国产不卡在线观看视频| av网页在线| 国产精品亚洲不卡a| 秋霞电影一区二区| 中文字幕一区二区三区手机版| 亚洲午夜性刺激影院| 超碰97成人| 天美星空大象mv在线观看视频| 亚洲综合一区在线| 国产视频三级在线观看播放| 国产99在线免费| 青青草97国产精品免费观看无弹窗版|