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

面試突擊:OkHttp 原理八連問

移動(dòng)開發(fā) Android
OkHttp 可以說是 Android 開發(fā)中最常見的網(wǎng)絡(luò)請(qǐng)求框架,OkHttp 使用方便,擴(kuò)展性強(qiáng),功能強(qiáng)大,OKHttp 源碼與原理也是面試中的常客。

[[434054]]

OkHttp 可以說是 Android 開發(fā)中最常見的網(wǎng)絡(luò)請(qǐng)求框架,OkHttp 使用方便,擴(kuò)展性強(qiáng),功能強(qiáng)大,OKHttp 源碼與原理也是面試中的常客。

但是 OKHttp 的源碼內(nèi)容比較多,想要學(xué)習(xí)它的源碼往往千頭萬緒,一時(shí)抓不住重點(diǎn). 本文從幾個(gè)問題出發(fā)梳理 OKHttp 相關(guān)知識(shí)點(diǎn),以便快速構(gòu)建 OKHttp 知識(shí)體,本文主要包括以下內(nèi)容

  1.   OKHttp 請(qǐng)求的整體流程是怎樣的?
  2.   OKHttp 分發(fā)器是怎樣工作的?
  3.   OKHttp 攔截器是如何工作的?
  4.   應(yīng)用攔截器和網(wǎng)絡(luò)攔截器有什么區(qū)別?
  5.   OKHttp 如何復(fù)用 TCP 連接?
  6.   OKHttp 空閑連接如何清除?
  7.   OKHttp 有哪些優(yōu)點(diǎn)?
  8.   OKHttp 框架中用到了哪些設(shè)計(jì)模式?

1. OKHttp請(qǐng)求整體流程介紹

首先來看一個(gè)最簡(jiǎn)單的 Http 請(qǐng)求是如何發(fā)送的。 

  1. val okHttpClient = OkHttpClient()  
  2. val request: RequestRequest = Request.Builder()  
  3.     .url("https://www.google.com/")  
  4.     .build()  
  5. okHttpClient.newCall(request).enqueue(object :Callback{  
  6.     override fun onFailure(call: Call, e: IOException) {  
  7.     }  
  8.     override fun onResponse(call: Call, response: Response) {  
  9.     }  
  10. }) 

這段代碼看起來比較簡(jiǎn)單,OkHttp 請(qǐng)求過程中最少只需要接觸 OkHttpClient、Request、Call、 Response,但是框架內(nèi)部會(huì)進(jìn)行大量的邏輯處理。

所有網(wǎng)絡(luò)請(qǐng)求的邏輯大部分集中在攔截器中,但是在進(jìn)入攔截器之前還需要依靠分發(fā)器來調(diào)配請(qǐng)求任務(wù)。關(guān)于分發(fā)器與攔截器,我們?cè)谶@里先簡(jiǎn)單介紹下,后續(xù)會(huì)有更加詳細(xì)的講解

  1.  分發(fā)器:內(nèi)部維護(hù)隊(duì)列與線程池,完成請(qǐng)求調(diào)配;
  2.  攔截器:五大默認(rèn)攔截器完成整個(gè)請(qǐng)求過程。

整個(gè)網(wǎng)絡(luò)請(qǐng)求過程大致如上所示

  1.  通過建造者模式構(gòu)建 OKHttpClient 與 Request
  2.  OKHttpClient 通過 newCall 發(fā)起一個(gè)新的請(qǐng)求
  3.  通過分發(fā)器維護(hù)請(qǐng)求隊(duì)列與線程池,完成請(qǐng)求調(diào)配
  4.  通過五大默認(rèn)攔截器完成請(qǐng)求重試,緩存處理,建立連接等一系列操作
  5.  得到網(wǎng)絡(luò)請(qǐng)求結(jié)果

2. OKHttp分發(fā)器是怎樣工作的?

分發(fā)器的主要作用是維護(hù)請(qǐng)求隊(duì)列與線程池,比如我們有100個(gè)異步請(qǐng)求,肯定不能把它們同時(shí)請(qǐng)求,而是應(yīng)該把它們排隊(duì)分個(gè)類,分為正在請(qǐng)求中的列表和正在等待的列表, 等請(qǐng)求完成后,即可從等待中的列表中取出等待的請(qǐng)求,從而完成所有的請(qǐng)求

而這里同步請(qǐng)求各異步請(qǐng)求又略有不同

同步請(qǐng)求 

  1. synchronized void executed(RealCall call) {  
  2.  runningSyncCalls.add(call);  

因?yàn)橥秸?qǐng)求不需要線程池,也不存在任何限制。所以分發(fā)器僅做一下記錄。后續(xù)按照加入隊(duì)列的順序同步請(qǐng)求即可

異步請(qǐng)求 

  1. synchronized void enqueue(AsyncCall call) {  
  2.  //請(qǐng)求數(shù)最大不超過64,同一Host請(qǐng)求不能超過5個(gè)  
  3.  if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost)    {  
  4.   runningAsyncCalls.add(call);  
  5.   executorService().execute(call);  
  6.  } else {  
  7.   readyAsyncCalls.add(call);  
  8.  }  

當(dāng)正在執(zhí)行的任務(wù)未超過最大限制64,同時(shí)同一 Host 的請(qǐng)求不超過5個(gè),則會(huì)添加到正在執(zhí)行隊(duì)列,同時(shí)提交給線程池。否則先加入等待隊(duì)列。每個(gè)任務(wù)完成后,都會(huì)調(diào)用分發(fā)器的 finished 方法,這里面會(huì)取出等待隊(duì)列中的任務(wù)繼續(xù)執(zhí)行

3. OKHttp攔截器是怎樣工作的?

經(jīng)過上面分發(fā)器的任務(wù)分發(fā),下面就要利用攔截器開始一系列配置了 

  1. # RealCall  
  2.   override fun execute(): Response {  
  3.     try {  
  4.       client.dispatcher.executed(this)  
  5.       return getResponseWithInterceptorChain()  
  6.     } finally {  
  7.       client.dispatcher.finished(this) 
  8.     }  
  9.   } 

我們?cè)賮砜聪?RealCall的execute方法,可以看出,最后返回了 getResponseWithInterceptorChain ,責(zé)任鏈的構(gòu)建與處理其實(shí)就是在這個(gè)方法里面 

  1. internal fun getResponseWithInterceptorChain(): Response {  
  2.     // Build a full stack of interceptors.  
  3.     val interceptors = mutableListOf<Interceptor>()  
  4.     interceptors += client.interceptors 
  5.     interceptors += RetryAndFollowUpInterceptor(client)  
  6.     interceptors += BridgeInterceptor(client.cookieJar)  
  7.     interceptors += CacheInterceptor(client.cache) 
  8.     interceptors += ConnectInterceptor  
  9.     if (!forWebSocket) {  
  10.       interceptors += client.networkInterceptors  
  11.     }  
  12.     interceptors += CallServerInterceptor(forWebSocket)  
  13.     val chain = RealInterceptorChain 
  14.         call = this,interceptorsinterceptors = interceptors,index = 0  
  15.     )  
  16.     val response = chain.proceed(originalRequest)  
  17.   } 

如上所示,構(gòu)建了一個(gè) OkHttp 攔截器的責(zé)任鏈

責(zé)任鏈,顧名思義,就是用來處理相關(guān)事務(wù)責(zé)任的一條執(zhí)行鏈,執(zhí)行鏈上有多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都有機(jī)會(huì)(條件匹配)處理請(qǐng)求事務(wù),如果某個(gè)節(jié)點(diǎn)處理完了就可以根據(jù)實(shí)際業(yè)務(wù)需求傳遞給下一個(gè)節(jié)點(diǎn)繼續(xù)處理或者返回處理完畢。

如上所示責(zé)任鏈添加的順序及作用,如下表所示:

攔截器 作用
應(yīng)用攔截器 拿到的是原始請(qǐng)求,可以添加一些自定義 header、通用參數(shù)、參數(shù)加密、網(wǎng)關(guān)接入等等。
RetryAndFollowUpInterceptor 處理錯(cuò)誤重試和重定向
BridgeInterceptor 應(yīng)用層和網(wǎng)絡(luò)層的橋接攔截器,主要工作是為請(qǐng)求添加cookie、添加固定的header,比如Host、Content-Length、Content-Type、User-Agent等等,然后保存響應(yīng)結(jié)果的cookie,如果響應(yīng)使用gzip壓縮過,則還需要進(jìn)行解壓。
CacheInterceptor 緩存攔截器,如果命中緩存則不會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求。
ConnectInterceptor 連接攔截器,內(nèi)部會(huì)維護(hù)一個(gè)連接池,負(fù)責(zé)連接復(fù)用、創(chuàng)建連接(三次握手等等)、釋放連接以及創(chuàng)建連接上的socket流。
networkInterceptors(網(wǎng)絡(luò)攔截器) 用戶自定義攔截器,通常用于監(jiān)控網(wǎng)絡(luò)層的數(shù)據(jù)傳輸。
CallServerInterceptor 請(qǐng)求攔截器,在前置準(zhǔn)備工作完成后,真正發(fā)起了網(wǎng)絡(luò)請(qǐng)求。

我們的網(wǎng)絡(luò)請(qǐng)求就是這樣經(jīng)過責(zé)任鏈一級(jí)一級(jí)的遞推下去,最終會(huì)執(zhí)行到 CallServerInterceptor的intercept 方法,此方法會(huì)將網(wǎng)絡(luò)響應(yīng)的結(jié)果封裝成一個(gè) Response 對(duì)象并 return。之后沿著責(zé)任鏈一級(jí)一級(jí)的回溯,最終就回到 getResponseWithInterceptorChain 方法的返回,如下圖所示:

4. 應(yīng)用攔截器和網(wǎng)絡(luò)攔截器有什么區(qū)別?

從整個(gè)責(zé)任鏈路來看,應(yīng)用攔截器是最先執(zhí)行的攔截器,也就是用戶自己設(shè)置 request 屬性后的原始請(qǐng)求,而網(wǎng)絡(luò)攔截器位于 ConnectInterceptor 和 CallServerInterceptor 之間,此時(shí)網(wǎng)絡(luò)鏈路已經(jīng)準(zhǔn)備好,只等待發(fā)送請(qǐng)求數(shù)據(jù)。它們主要有以下區(qū)別

    1.  首先,應(yīng)用攔截器在 RetryAndFollowUpInterceptor 和 CacheInterceptor 之前,所以一旦發(fā)生錯(cuò)誤重試或者網(wǎng)絡(luò)重定向,網(wǎng)絡(luò)攔截器可能執(zhí)行多次,因?yàn)橄喈?dāng)于進(jìn)行了二次請(qǐng)求,但是應(yīng)用攔截器永遠(yuǎn)只會(huì)觸發(fā)一次。另外如果在 CacheInterceptor 中命中了緩存就不需要走網(wǎng)絡(luò)請(qǐng)求了,因此會(huì)存在短路網(wǎng)絡(luò)攔截器的情況。

    2.  其次,除了 CallServerInterceptor 之外,每個(gè)攔截器都應(yīng)該至少調(diào)用一次 realChain.proceed 方法。實(shí)際上在應(yīng)用攔截器這層可以多次調(diào)用 proceed 方法(本地異常重試)或者不調(diào)用 proceed 方法(中斷),但是網(wǎng)絡(luò)攔截器這層連接已經(jīng)準(zhǔn)備好,可且僅可調(diào)用一次 proceed 方法。

    3.  最后,從使用場(chǎng)景看,應(yīng)用攔截器因?yàn)橹粫?huì)調(diào)用一次,通常用于統(tǒng)計(jì)客戶端的網(wǎng)絡(luò)請(qǐng)求發(fā)起情況;而網(wǎng)絡(luò)攔截器一次調(diào)用代表了一定會(huì)發(fā)起一次網(wǎng)絡(luò)通信,因此通常可用于統(tǒng)計(jì)網(wǎng)絡(luò)鏈路上傳輸?shù)臄?shù)據(jù)。

5. OKHttp如何復(fù)用TCP連接?

ConnectInterceptor 的主要工作就是負(fù)責(zé)建立 TCP 連接,建立 TCP 連接需要經(jīng)歷三次握手四次揮手等操作,如果每個(gè) HTTP 請(qǐng)求都要新建一個(gè) TCP 消耗資源比較多 而 Http1.1 已經(jīng)支持 keep-alive ,即多個(gè) Http 請(qǐng)求復(fù)用一個(gè) TCP 連接,OKHttp 也做了相應(yīng)的優(yōu)化,下面我們來看下 OKHttp 是怎么復(fù)用 TCP 連接的

ConnectInterceptor 中查找連接的代碼會(huì)最終會(huì)調(diào)用到 ExchangeFinder.findConnection 方法,具體如下: 

  1. # ExchangeFinder  
  2. //為承載新的數(shù)據(jù)流 尋找 連接。尋找順序是 已分配的連接、連接池、新建連接  
  3. private RealConnection findConnection(int connectTimeout, int readTimeout, int writeTimeout,  
  4.     int pingIntervalMillis, boolean connectionRetryEnabled) throws IOException {  
  5.   synchronized (connectionPool) {  
  6.     // 1.嘗試使用 已給數(shù)據(jù)流分配的連接.(例如重定向請(qǐng)求時(shí),可以復(fù)用上次請(qǐng)求的連接)  
  7.     releasedConnection = transmitter.connection;  
  8.     result = transmitter.connection;  
  9.     if (result == null) {  
  10.       // 2. 沒有已分配的可用連接,就嘗試從連接池獲取。(連接池稍后詳細(xì)講解)  
  11.       if (connectionPool.transmitterAcquirePooledConnection(address, transmitter, null, false)) {  
  12.         result = transmitter.connection;  
  13.       }  
  14.     }  
  15.   }  
  16.   synchronized (connectionPool) {  
  17.     if (newRouteSelection) {  
  18.       //3. 現(xiàn)在有了IP地址,再次嘗試從連接池獲取。可能會(huì)因?yàn)檫B接合并而匹配。(這里傳入了routes,上面的傳的null)  
  19.       routes = routeSelection.getAll(); 
  20.      if (connectionPool.transmitterAcquirePooledConnection(address, transmitter, routes, false)) {  
  21.         foundPooledConnection = true 
  22.         result = transmitter.connection;  
  23.       }  
  24.     }  
  25.   // 4.第二次沒成功,就把新建的連接,進(jìn)行TCP + TLS 握手,與服務(wù)端建立連接. 是阻塞操作  
  26.   result.connect(connectTimeout, readTimeout, writeTimeout, pingIntervalMillis,  
  27.       connectionRetryEnabled, call, eventListener);  
  28.   synchronized (connectionPool) {  
  29.     // 5. 最后一次嘗試從連接池獲取,注意最后一個(gè)參數(shù)為true,即要求 多路復(fù)用(http2.0)  
  30.     //意思是,如果本次是http2.0,那么為了保證 多路復(fù)用性,(因?yàn)樯厦娴奈帐植僮鞑皇蔷€程安全)會(huì)再次確認(rèn)連接池中此時(shí)是否已有同樣連接  
  31.     if (connectionPool.transmitterAcquirePooledConnection(address, transmitter, routes, true)) {  
  32.       // 如果獲取到,就關(guān)閉我們創(chuàng)建里的連接,返回獲取的連接  
  33.       result = transmitter.connection;  
  34.     } else {  
  35.       //最后一次嘗試也沒有的話,就把剛剛新建的連接存入連接池  
  36.       connectionPool.put(result);  
  37.     }  
  38.   }  
  39.   return result;  

上面精簡(jiǎn)了部分代碼,可以看出,連接攔截器使用了5種方法查找連接:

  1.  首先會(huì)嘗試使用 已給請(qǐng)求分配的連接。(已分配連接的情況例如重定向時(shí)的再次請(qǐng)求,說明上次已經(jīng)有了連接)
  2.  若沒有已分配的可用連接,就嘗試從連接池中 匹配獲取。因?yàn)榇藭r(shí)沒有路由信息,所以匹配條件:address 一致—— host、port、代理等一致,且匹配的連接可以接受新的請(qǐng)求。
  3.  若從連接池沒有獲取到,則傳入 routes 再次嘗試獲取,這主要是針對(duì) Http2.0 的一個(gè)操作, Http2.0 可以復(fù)用 square.com 與 square.ca 的連接
  4.  若第二次也沒有獲取到,就創(chuàng)建 RealConnection 實(shí)例,進(jìn)行 TCP + TLS 握手,與服務(wù)端建立連接。
  5.  此時(shí)為了確保 Http2.0 連接的多路復(fù)用性,會(huì)第三次從連接池匹配。因?yàn)樾陆⒌倪B接的握手過程是非線程安全的,所以此時(shí)可能連接池新存入了相同的連接。
  6.  第三次若匹配到,就使用已有連接,釋放剛剛新建的連接;若未匹配到,則把新連接存入連接池并返回。

以上就是連接攔截器嘗試復(fù)用連接的操作,流程圖如下:

6. OKHttp空閑連接如何清除?

上面說到我們會(huì)建立一個(gè) TCP 連接池,但如果沒有任務(wù)了,空閑的連接也應(yīng)該及時(shí)清除,OKHttp 是如何做到的呢? 

  1. # RealConnectionPool  
  2.  private val cleanupQueue: TaskQueue = taskRunner.newQueue()  
  3.  private val cleanupTask = object : Task("$okHttpName ConnectionPool") {  
  4.    override fun runOnce(): Long = cleanup(System.nanoTime())  
  5.  }  
  6.  long cleanup(long now) {  
  7.    int inUseConnectionCount = 0;//正在使用的連接數(shù)  
  8.    int idleConnectionCount = 0;//空閑連接數(shù)  
  9.    RealConnection longestIdleConnection = null;//空閑時(shí)間最長(zhǎng)的連接  
  10.    long longestIdleDurationNs = Long.MIN_VALUE;//最長(zhǎng)的空閑時(shí)間 
  11.    //遍歷連接:找到待清理的連接, 找到下一次要清理的時(shí)間(還未到最大空閑時(shí)間)  
  12.    synchronized (this) {  
  13.      for (Iterator<RealConnection> i = connections.iterator(); i.hasNext(); ) {  
  14.        RealConnection connection = i.next();  
  15.        //若連接正在使用,continue,正在使用連接數(shù)+1  
  16.        if (pruneAndGetAllocationCount(connection, now) > 0) {  
  17.          inUseConnectionCount++;  
  18.          continue;  
  19.        }  
  20.  //空閑連接數(shù)+1  
  21.        idleConnectionCount++;  
  22.        // 賦值最長(zhǎng)的空閑時(shí)間和對(duì)應(yīng)連接  
  23.        long idleDurationNs = now - connection.idleAtNanos;  
  24.        if (idleDurationNs > longestIdleDurationNs) {  
  25.          longestIdleDurationNs = idleDurationNs 
  26.          longestIdleConnection = connection 
  27.        }  
  28.      }  
  29.   //若最長(zhǎng)的空閑時(shí)間大于5分鐘 或 空閑數(shù) 大于5,就移除并關(guān)閉這個(gè)連接  
  30.      if (longestIdleDurationNs >= this.keepAliveDurationNs  
  31.          || idleConnectionCount > this.maxIdleConnections) {  
  32.        connections.remove(longestIdleConnection);  
  33.      } else if (idleConnectionCount > 0) {  
  34.        // else,就返回 還剩多久到達(dá)5分鐘,然后wait這個(gè)時(shí)間再來清理  
  35.        return keepAliveDurationNs - longestIdleDurationNs;  
  36.      } else if (inUseConnectionCount > 0) {  
  37.        //連接沒有空閑的,就5分鐘后再嘗試清理.  
  38.        return keepAliveDurationNs;  
  39.      } else {  
  40.        // 沒有連接,不清理  
  41.        cleanupRunning = false 
  42.        return -1;  
  43.      }  
  44.    }  
  45. //關(guān)閉移除的連接  
  46.    closeQuietly(longestIdleConnection.socket());  
  47.    //關(guān)閉移除后 立刻 進(jìn)行下一次的 嘗試清理  
  48.    return 0;  
  49.  } 

思路還是很清晰的:

    1.  在將連接加入連接池時(shí)就會(huì)啟動(dòng)定時(shí)任務(wù)

    2.  有空閑連接的話,如果最長(zhǎng)的空閑時(shí)間大于5分鐘 或 空閑數(shù) 大于5,就移除關(guān)閉這個(gè)最長(zhǎng)空閑連接;如果 空閑數(shù) 不大于5 且 最長(zhǎng)的空閑時(shí)間不大于5分鐘,就返回到5分鐘的剩余時(shí)間,然后等待這個(gè)時(shí)間再來清理。

    3.  沒有空閑連接就等5分鐘后再嘗試清理。

    4.  沒有連接不清理。

流程如下圖所示:

7. OKHttp有哪些優(yōu)點(diǎn)?

  •  使用簡(jiǎn)單,在設(shè)計(jì)時(shí)使用了外觀模式,將整個(gè)系統(tǒng)的復(fù)雜性給隱藏起來,將子系統(tǒng)接口通過一個(gè)客戶端 OkHttpClient 統(tǒng)一暴露出來。
  •  擴(kuò)展性強(qiáng),可以通過自定義應(yīng)用攔截器與網(wǎng)絡(luò)攔截器,完成用戶各種自定義的需求
  •  功能強(qiáng)大,支持 Spdy、Http1.X、Http2、以及 WebSocket 等多種協(xié)議
  •  通過連接池復(fù)用底層 TCP(Socket),減少請(qǐng)求延時(shí)
  •  無縫的支持 GZIP 減少數(shù)據(jù)流量
  •  支持?jǐn)?shù)據(jù)緩存,減少重復(fù)的網(wǎng)絡(luò)請(qǐng)求
  •  支持請(qǐng)求失敗自動(dòng)重試主機(jī)的其他 ip,自動(dòng)重定向

8. OKHttp框架中用到了哪些設(shè)計(jì)模式?

  •  構(gòu)建者模式:OkHttpClient 與 Request 的構(gòu)建都用到了構(gòu)建者模式
  •  外觀模式:OkHttp使用了外觀模式,將整個(gè)系統(tǒng)的復(fù)雜性給隱藏起來,將子系統(tǒng)接口通過一個(gè)客戶端 OkHttpClient 統(tǒng)一暴露出來
  •  責(zé)任鏈模式: OKHttp 的核心就是責(zé)任鏈模式,通過5個(gè)默認(rèn)攔截器構(gòu)成的責(zé)任鏈完成請(qǐng)求的配置
  •  享元模式: 享元模式的核心即池中復(fù)用, OKHttp 復(fù)用 TCP 連接時(shí)用到了連接池,同時(shí)在異步請(qǐng)求中也用到了線程池  

 

責(zé)任編輯:龐桂玉 來源: 安卓開發(fā)精選
相關(guān)推薦

2022-02-14 08:25:50

Go語言面試

2010-05-13 10:40:56

富士康

2024-08-07 13:40:00

2021-07-12 07:08:52

TCP協(xié)議面試

2014-12-22 11:28:01

2020-09-30 18:19:27

RedisJava面試

2014-12-21 08:49:53

2022-01-05 09:55:26

asynawait前端

2022-04-11 07:40:45

synchroniz靜態(tài)方法程序

2022-02-28 07:01:22

線程中斷interrupt

2022-07-11 07:10:48

HTTP協(xié)議類型

2022-05-14 21:19:22

ThreadLocaJDKsynchroniz

2019-12-19 09:23:45

Java多線程數(shù)據(jù)

2015-04-07 16:09:28

鋼七連華為

2022-05-05 07:38:32

volatilJava并發(fā)

2022-06-06 07:35:26

MySQLInnoDBMyISAM

2020-07-28 00:58:20

IP地址子網(wǎng)TCP

2022-04-20 07:47:00

notify喚醒線程JVM

2022-07-27 07:36:01

TCP可靠性

2022-07-06 07:35:19

group byMySQL
點(diǎn)贊
收藏

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

亚洲高清在线一区| 黄网站在线观| 国产一区二区三区国产| 国语自产精品视频在线看一大j8 | 韩日精品视频一区| 久久久免费观看| 夜夜春很很躁夜夜躁| 欧美一级大片在线视频| 日韩欧美在线字幕| 免费看黄色a级片| 国产视频二区在线观看| 国产成人免费在线观看| 琪琪第一精品导航| 欧美丰满艳妇bbwbbw| 国产欧美日韩一区二区三区四区| 日韩一区二区三区高清免费看看| 欧美黄网站在线观看| avove在线播放| 老司机凹凸av亚洲导航| 欧美日韩1234| 欧美 国产 日本| 在线看女人毛片| 欧美韩国日本一区| 麻豆传媒一区| 亚洲第一视频在线| 国内精品久久久久影院薰衣草| 日韩免费av在线| 国产香蕉视频在线| 欧美视频网站| 久久久国产一区二区三区| 88久久精品无码一区二区毛片| 亚洲精品国产九九九| 欧美久久高跟鞋激| 在线免费视频a| 欧亚在线中文字幕免费| 一区二区三区欧美激情| 中文字幕中文字幕一区三区| 韩国中文免费在线视频| 99久久夜色精品国产网站| 亚洲自拍小视频免费观看| 依依成人在线视频| 日韩av中文在线观看| 2025国产精品视频| 亚洲黄色小说图片| 国产精品视频| 97超级碰在线看视频免费在线看| 精品在线视频观看| 狠狠爱综合网| 久久久久久久久久久亚洲| 久久久久人妻一区精品色欧美| 亚洲字幕久久| 色综合男人天堂| 亚洲精品卡一卡二| 重囗味另类老妇506070| 美女999久久久精品视频| 午夜黄色福利视频| 97精品视频| 久久精品视频在线播放| 黄色一级大片在线免费观看| 午夜av一区| 欧美日韩成人精品| 久久婷婷一区二区| 伊人成人在线视频| 午夜精品视频在线| 中文字幕国产在线观看| 日韩经典中文字幕一区| 国产精品视频网址| 国产精品久久久久久久久毛片| 久久精品国内一区二区三区| 成人免费午夜电影| 精品国产九九九| 成人久久视频在线观看| 精品伊人久久大线蕉色首页| 男人的天堂在线| 国产精品久久久久aaaa樱花 | 日本免费不卡| 国产丝袜欧美中文另类| 亚洲午夜精品久久久久久浪潮| 午夜视频在线| 亚洲影院在线观看| 欧美日韩国产精品激情在线播放| av在线日韩| 欧美一区二区三区在线电影| 亚洲成年人av| 欧美午夜精彩| 欧美第一黄色网| 色屁屁影院www国产高清麻豆| 美女在线一区二区| 国产98在线|日韩| 国产一区二区三区福利| 自拍偷拍国产精品| 精品国产一区三区| 欧美午夜三级| 亚洲国产成人在线视频| 国产又粗又硬视频| 国产精品第十页| 国产精品成久久久久三级| 国产后入清纯学生妹| 久久婷婷国产综合国色天香| 正义之心1992免费观看全集完整版| 免费在线看污片| 在线观看日韩精品| 性活交片大全免费看| 久久国产成人精品| 97在线视频免费观看| 亚洲一区精品在线观看| 不卡的av电影在线观看| 在线观看日韩羞羞视频| 日韩在线伦理| 日韩免费视频线观看| 色欲av无码一区二区三区| 91精品一区二区三区综合在线爱| 欧美亚洲视频一区二区| www.色视频| 国产精品久久久久婷婷二区次| 国自产拍偷拍精品啪啪一区二区| 日韩毛片免费看| 国产亚洲精品91在线| 日本一级黄色录像| 国产在线一区二区综合免费视频| 欧美不卡在线一区二区三区| 九色91在线| 欧美一区二区女人| 天天干天天操天天拍| 午夜在线一区二区| 国产精品加勒比| 黄色免费网站在线观看| 欧美影片第一页| 李宗瑞91在线正在播放| 99热在线精品观看| 91久久伊人青青碰碰婷婷| 伊人在线视频| 欧美日韩中字一区| 国产一区二区三区精品在线| 久久xxxx精品视频| 久久精品国产综合精品| 9999在线视频| 精品免费99久久| 久久精品www| 国产精品99久久久久久宅男| 日本福利视频导航| 欧美aaaaaa| 久久精品福利视频| 91成人国产综合久久精品| 国产精品网友自拍| 日韩精品视频一二三| 精品一区二区三区的国产在线观看| 日韩免费在线视频| 毛片免费在线观看| 欧美午夜不卡在线观看免费| 国产精品18在线| 久久99精品国产.久久久久久| 亚洲一卡二卡三卡四卡无卡网站在线看| 欧美aaa大片视频一二区| 亚洲色图狂野欧美| 中文字幕 日韩有码| 国产精品全国免费观看高清 | 国产三级欧美三级日产三级99| 神马影院我不卡| 粉嫩av一区二区三区四区五区| 在线视频一区二区| 国产又黄又大又爽| 亚洲精品va在线观看| 午夜影院福利社| 国产日韩亚洲| 青青影院一区二区三区四区| 国外成人福利视频| 欧美另类老女人| 亚洲欧洲精品视频| 欧美在线视频全部完| 中文字幕无码日韩专区免费| 国产精品亚洲成人| 97成人在线观看视频| 欧美日韩精品在线一区| 51午夜精品| 亚洲欧美小说色综合小说一区| 亚洲性生活视频| 国产视频手机在线观看| 精品人伦一区二区三区蜜桃免费| 国产三级av在线播放| 国产精品综合二区| 黄色免费观看视频网站| 日韩一区二区在线免费| 鬼打鬼之黄金道士1992林正英| 欧美大胆性生话| 久久精品中文字幕| 五月婷婷久久久| 欧美蜜桃一区二区三区| 日韩黄色一级大片| 中文字幕一区二区三区精华液| 国产精品成人99一区无码| 日韩高清在线一区| 天堂8在线天堂资源bt| 国产精品免费99久久久| 国产99视频精品免费视频36| 国产综合av| 国产做受高潮69| 在线毛片网站| 国产视频精品免费播放| 国产强被迫伦姧在线观看无码| 欧美日韩视频在线| 国产稀缺精品盗摄盗拍| 91蝌蚪国产九色| 手机看片国产精品| 日韩黄色片在线观看| 欧美日韩福利在线| 97国产成人高清在线观看| 欧美不卡三区| 精品午夜电影| 91最新在线免费观看| 国产精品久久久久av电视剧| 久久理论片午夜琪琪电影网| 精品视频在线一区二区| 亚洲视频日韩精品| 日韩在线观看视频网站| 91麻豆精品国产91久久久久久久久 | 国产精品亚洲激情| 亚洲精品福利电影| 午夜精品久久17c| 在线网址91| 日韩在线观看免费高清| 国产黄色免费在线观看| 日韩精品福利在线| 神马午夜精品95| 欧美一区二区三区四区在线观看 | 国产成人免费在线视频| 久久国产激情视频| 久久在线精品| 久久国产成人精品国产成人亚洲| 欧美日韩综合| 艳母动漫在线观看| 99久久亚洲精品蜜臀| 色中色综合成人| 欧美一级淫片| 欧洲精品久久| 国产精品中文字幕亚洲欧美| 久久爱av电影| 首页亚洲中字| 久久国产精品99久久久久久丝袜| 国产日韩三级| 精品乱码一区| 青青视频一区二区| 久久精品日产第一区二区三区乱码| 国产精品对白久久久久粗| 97视频热人人精品| 国产成人福利av| 国产九色91| 综合干狼人综合首页| 欧美日韩三区四区| 欧美一区二区三| 国产91av视频在线观看| 亚洲大全视频| 中国黄色录像片| 精品福利电影| 日韩少妇内射免费播放18禁裸乳| 亚洲一区日本| 妓院一钑片免看黄大片| 日韩va亚洲va欧美va久久| 欧美一级xxxx| 国产精品一区二区x88av| 91porn在线| 91社区在线播放| 欧美三级视频网站| 中文字幕一区二区三区不卡| 欧美精品99久久久| 精品毛片网大全| 国产精品久久久久久久久夜色| 91福利国产精品| 国产手机av在线| 亚洲国产欧美日韩精品| 国产视频精品久久| 欧美大尺度在线观看| bl视频在线免费观看| 国产成人久久久精品一区| 欧美啪啪网站| 国产精品久久久久久久免费大片 | 精品无码av无码免费专区| 亚洲精选91| www.99在线| 国产v综合v亚洲欧| 亚洲久久久久久久| 亚洲黄一区二区三区| 日韩欧美在线观看免费| 91.成人天堂一区| 日韩在线观看视频一区二区三区| 亚洲一区二区精品| 性欧美videos高清hd4k| 欧美在线视频一区二区| 涩涩涩久久久成人精品| 国产伦精品一区二区三区照片| 欧美裸体在线版观看完整版| 国产精品igao激情视频| 久久久久久穴| 女性生殖扒开酷刑vk| 国产偷v国产偷v亚洲高清| 久草中文在线视频| 色94色欧美sute亚洲13| 亚洲第一天堂影院| 中文字幕在线亚洲| 九色porny视频在线观看| 91亚洲精品视频| 精品国产乱码久久久久久果冻传媒| www.激情网| 久久99日本精品| 中国毛片在线观看| 亚洲一区二区视频在线| 一卡二卡三卡在线观看| 亚洲香蕉成人av网站在线观看| 国产99re66在线视频| 国产日本欧美一区二区三区在线 | 久久伊人久久| 日韩影片在线播放| 久久aⅴ国产紧身牛仔裤| 自拍偷拍激情视频| 国产精品久久久爽爽爽麻豆色哟哟| 国产精品一区二区6| 日韩欧美综合在线| 91精品专区| 国产精品久久久亚洲| 少妇高潮一区二区三区| 国产精品12345| 国产乱人伦精品一区二区在线观看| 免费看黄色三级| 欧美小视频在线观看| 天堂在线资源网| 欧美激情三级免费| 精品99re| 日本丰满少妇黄大片在线观看| 久久精品国产免费| 我不卡一区二区| 欧美性猛交xxxx偷拍洗澡| 婷婷综合激情网| 欧美精品成人在线| 亚洲成人五区| 成人在线观看毛片| 国产精品一二三四| 亚洲色图综合区| 欧美一级片在线观看| 黄色动漫在线观看| 92看片淫黄大片欧美看国产片| 欧美成免费一区二区视频| 亚洲综合欧美在线| 国产精品美女久久久久av爽李琼| 国产一卡二卡三卡| 永久555www成人免费| 成人免费一区| 伊甸园精品99久久久久久| 久久精品国产在热久久| 在线观看黄网址| 欧美大片在线观看一区二区| 日本不卡影院| 精品日本一区二区三区| 午夜在线视频观看日韩17c| 久久只有这里有精品| 欧美性高清videossexo| 日本激情在线观看| 91久久久久久久一区二区| 亚洲国产精品成人| 亚洲一区和二区| 欧美午夜美女看片| 福利视频在线播放| 成人精品一区二区三区电影黑人| 午夜精品电影| 亚洲国产综合视频| 欧美怡红院视频| 理论片午午伦夜理片在线播放| 亚洲在线免费观看| 1024成人| 久久精品色妇熟妇丰满人妻| 这里是久久伊人| 福利写真视频网站在线| 欧美一区二区三区四区在线观看地址 | 欧美在线视频a| 日韩国产综合| 国产精品偷伦视频免费观看了| 性感美女极品91精品| 番号集在线观看| 91视频婷婷| 久久久久久黄| 青青草精品在线视频| 国产视频在线观看一区二区| 国内自拍亚洲| 鲁一鲁一鲁一鲁一澡| 国产精品久久久久久久裸模| 亚洲精品国偷拍自产在线观看蜜桃| 97香蕉超级碰碰久久免费软件 | 亚洲网一区二区三区| 久久久久久久少妇| 亚洲女与黑人做爰| 日夜干在线视频| 亚洲自拍小视频| 日韩电影在线看| 国产一级视频在线观看| 中文字幕日韩专区| 国产伦精品一区二区三区在线播放| 美女喷白浆视频| 午夜精品福利久久久| 欧洲不卡av| 欧美精品免费观看二区| 国产二区国产一区在线观看|