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

33張圖探秘OpenFeign核心架構原理

開發 架構
當調用動態代理方法的時候,Feign就會將上述解析出來的Http請求基本參數和方法入參組裝成一個Http請求,然后發送Http請求,獲取響應,再根據響應的內容的類型將響應體的內容轉換成對應的類型‘’這就是Feign的大致原理。

大家好,我是三友~~

在很久之前,我寫過兩篇關于OpenFeign和Ribbon這兩個SpringCloud核心組件架構原理的文章

但是說實話,從我現在的角度來看,這兩篇文章的結構和內容其實還可以更加完善

剛好我最近打算整個SpringCloud各個組件架構原理的小冊子

所以趁著這個機會,我就來重新寫一下這兩篇文章,彌補之前文章的不足

這一篇文章就先來講一講OpenFeign的核心架構原理

整篇文章大致分為以下四個部分的內容:

第一部分,脫離于SpringCloud,原始的Feign是什么樣的?

第二部分,Feign的核心組件有哪些,整個執行鏈路是什么樣的?

第三部分,SpringCloud是如何把Feign融入到自己的生態的?

第四部分,OpenFeign有幾種配置方式,各種配置方式的優先級是什么樣的?

好了,話不多說,接下來就直接進入主題,來探秘OpenFeign核心架構原理

原始Feign是什么樣的?

在日常開發中,使用Feign很簡單,就三步

第一步:引入依賴

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
     <version>2.2.5.RELEASE</version>
</dependency>

第二步:在啟動引導類加上@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

第三步:寫個FeignClient接口

@FeignClient(name = "order")
@RequestMapping("/order")
public interface OrderApiClient {

    @GetMapping
    Order queryOrder(@RequestParam("orderId") Long orderId);

}

之后當我們要使用時,只需要注入OrderApiClient對象就可以了

雖然使用方便,但這并不是Feign最原始的使用方式,而是SpringCloud整合Feign之后的使用方式

Feign最開始是由Netflix開源的

后來SpringCloud就將Feign進行了一層封裝,整合到自己的生態,讓Feign使用起來更加簡單

并同時也給它起了一個更高級的名字,OpenFeign

接下來文章表述有時可能并沒有嚴格區分Feign和OpenFeign的含義,你知道是這么個意思就行了。

Feign本身有自己的使用方式,也有類似Spring MVC相關的注解,如下所示:

public interface OrderApiClient {

    @RequestLine("GET /order/{orderId}")
    Order queryOrder(@Param("orderId") Long orderId);

}

OrderApiClient對象需要手動通過Feign.builder()來創建

public class FeignDemo {

    public static void main(String[] args) {
        OrderApiClient orderApiClient = Feign.builder()
                .target(OrderApiClient.class, "http://localhost:8088");
        orderApiClient.queryOrder(9527L);
    }

}

Feign的本質:動態代理 + 七大核心組件

相信稍微了解Feign的小伙伴都知道,Feign底層其實是基于JDK動態代理來的

所以Feign.builder()最終構造的是一個代理對象

Feign在構建動態代理的時候,會去解析方法上的注解和參數

獲取Http請求需要用到基本參數以及和這些參數和方法參數的對應關系

比如Http請求的url、請求體是方法中的第幾個參數、請求頭是方法中的第幾個參數等等

之后在構建Http請求時,就知道請求路徑以及方法的第幾個參數對應是Http請求的哪部分數據

當調用動態代理方法的時候,Feign就會將上述解析出來的Http請求基本參數和方法入參組裝成一個Http請求

然后發送Http請求,獲取響應,再根據響應的內容的類型將響應體的內容轉換成對應的類型

這就是Feign的大致原理

圖片圖片

在整個Feign動態代理生成和調用過程中,需要依靠Feign的一些核心組件來協調完成

如下圖所示是Feign的一些核心組件

這些核心組件可以通過Feign.builder()進行替換

由于組件很多,這里我挑幾個重要的跟大家講一講

1、Contract

圖片圖片

前面在說Feign在構建動態代理的時候,會去解析方法上的注解和參數,獲取Http請求需要用到基本參數

而這個Contract接口的作用就是用來干解析這件事的

Contract的默認實現是解析Feign自己原生注解的

圖片圖片

解析時,會為每個方法生成一個MethodMetadata對象

圖片圖片

MethodMetadata就封裝了Http請求需要用到基本參數以及這些參數和方法參數的對應關系

SpringCloud在整合Feign的時候,為了讓Feign能夠識別Spring MVC的注解,所以就自己實現了Contract接口

2、Encoder

通過名字也可以看出來,這個其實用來編碼的

具體的作用就是將請求體對應的方法參數序列化成字節數組

Feign默認的Encoder實現只支持請求體對應的方法參數類型為String和字節數組

圖片圖片

如果是其它類型,比如說請求體對應的方法參數類型為AddOrderRequest.class類型,此時就無法對AddOrderRequest對象進行序列化

這就導致默認情況下,這個Encoder的實現很難用

于是乎,Spring就實現了Encoder接口

圖片圖片

可以將任意請求體對應的方法參數類型對象序列化成字節數組

3、Decoder

Decoder的作用恰恰是跟Encoder相反

Encoder是將請求體對應的方法參數序列化成字節數組

而Decoder其實就是將響應體由字節流反序列化成方法返回值類型的對象

Decoder默認情況下跟Encoder的默認情況是一樣的,只支持反序列化成字節數組或者是String

所以,Spring也同樣實現了Decoder,擴展它的功能

圖片圖片

可以將響應體對應的字節流反序列化成任意返回值類型對象

4、Client

圖片

從接口方法的參數和返回值其實可以看出,這其實就是動態代理對象最終用來執行Http請求的組件

默認實現就是通過JDK提供的HttpURLConnection來的

除了這個默認的,Feign還提供了基于HttpClient和OkHttp實現的

在項目中,要想替換默認的實現,只需要引入相應的依賴,在構建Feign.builder()時設置一下就行了

SpringCloud環境底下會根據引入的依賴自動進行設置

除了上述的三個實現,最最重要的當然是屬于它基于負載均衡的實現

如下是OpenFeign用來整合Ribbon的核心實現

圖片圖片

這個Client會根據服務名,從Ribbon中獲取一個服務實例的信息,也就是ip和端口

之后會通過ip和端口向服務實例發送Http請求

5、InvocationHandlerFactory

InvocationHandler我相信大家應該都不陌生

對于JDK動態代理來說,必須得實現InvocationHandler才能創建動態代理

InvocationHandler的invoke方法實現就是動態代理走的核心邏輯

而InvocationHandlerFactory其實就是創建InvocationHandler的工廠

所以,這里就可以猜到,通過InvocationHandlerFactory創建的InvocationHandler應該就是Feign動態代理執行的核心邏輯

InvocationHandlerFactory默認實現是下面這個

SpringCloud環境下默認也是使用它的這個默認實現

所以,我們直接去看看InvocationHandler的實現類FeignInvocationHandler

圖片圖片

從實現可以看出,除了Object類的一些方法,最終會調用方法對應的MethodHandler的invoke方法

所以注意注意,這個MethodHandler就封裝了Feign執行Http調用的核心邏輯,很重要,后面還會提到

圖片圖片

雖然說默認情況下SpringCloud使用是默認實現,最終使用FeignInvocationHandler

但是當其它框架整合SpringCloud生態的時候,為了適配OpenFeign,有時會自己實現InvocationHandler

比如常見的限流熔斷框架Hystrix和Sentinel都實現了自己的InvocationHandler

這樣就可以對MethodHandler執行前后,也就是Http接口調用前后進行限流降級等操作。

6、RequestInterceptor

圖片圖片

RequestInterceptor它其實是一個在發送請求前的一個攔截接口

通過這個接口,在發送Http請求之前再對Http請求的內容進行修改

比如我們可以設置一些接口需要的公共參數,如鑒權token之類的

@Component
public class TokenRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("token", "token值");
    }

}

7、Retryer

這是一個重試的組件,默認實現如下

默認情況下,最大重試5次

在SpringCloud下,并沒有使用上面那個實現,而使用的是下面這個實現

圖片圖片

所以,SpringCloud下默認是不會進行重試

小總結

這一節主要是介紹了7個Feign的核心組件以及Spring對應的擴展實現

為了方便你查看,我整理了如下表格

接口

作用

Feign默認實現

Spring實現

Contract

解析方法注解和參數,將Http請求參數和方法參數對應

Contract.Default

SpringMvcContract

Encoder

將請求體對應的方法參數序列化成字節數組

Encoder.Default

SpringEncoder

Decoder

將響應體的字節流反序列化成方法返回值類型對象

Decoder.Default

SpringDecoder

Client

發送Http請求

Client.Default

LoadBalancerFeignClient

InvocationHandlerFactory

InvocationHandler工廠,動態代理核心邏輯

InvocationHandlerFactory.Default

RequestInterceptor

在發送Http請求之前,再對Http請求的內容進行攔截修改

Retryer

重試組件

Retryer.Default

除了這些之外,還有一些其它組件這里就沒有說了

比如日志級別Logger.Level,日志輸出Logger,有興趣的可以自己查看

Feign核心運行原理分析

上一節說了Feign核心組件,這一節我們來講一講Feign核心運行原理,主要分為兩部分內容:

  • 動態代理生成原理
  • 一次Feign的Http調用執行過程

1、動態代理生成原理

這里我先把上面的Feign原始使用方式的Demo代碼再拿過來

public class FeignDemo {

    public static void main(String[] args) {
        OrderApiClient orderApiClient = Feign.builder()
                .target(OrderApiClient.class, "http://localhost:8088");
        orderApiClient.queryOrder(9527L);
    }

}

通過Demo可以看出,最后是通過Feign.builder().target(xx)獲取到動態代理的

而上述代碼執行邏輯如下所示:

圖片圖片

最終會調用ReflectiveFeign的newInstance方法來創建動態代理對象

而ReflectiveFeign內部設置了前面提到的一些核心組件

接下我們來看看newInstance方法

這個方法主要就干兩件事:

第一件事首先解析接口,構建每個方法對應的MethodHandler

MethodHandler在前面講InvocationHandlerFactory特地提醒過

動態代理(FeignInvocationHandler)最終會調用MethodHandler來處理Feign的一次Http調用

在解析接口的時候,就會用到前面提到的Contract來解析方法參數和注解,生成MethodMetadata,這里我代碼我就不貼了

第二件事通過InvocationHandlerFactory創建InvocationHandler

然后再構建出接口的動態代理對象

ok,到這其實就走完了動態代理的生成過程

所以動態代理生成邏輯很簡單,總共也沒幾行代碼,畫個圖來總結一下

圖片圖片

2、一次Feign的Http調用執行過程

前面說了,調用接口動態代理的方式時,通過InvocationHandler(FeignInvocationHandler),最終交給MethodHandler的invoke方法來執行

MethodHandler是一個接口,最終會走到它的實現類SynchronousMethodHandler的invoke方法實現

SynchronousMethodHandler中的屬性就是我們前面提到的一些組件

由于整個代碼調用執行鏈路比較長,這里我就不截代碼了,有興趣的可以自己翻翻

不過這里我畫了一張圖,可以通過這張圖來大致分析整個Feign一次Http調用的過程

圖片圖片

  • 首先就是前面說的,進入FeignInvocationHandler,找到方法對應的SynchronousMethodHandler,調用invoke方法實現
  • 之后根據MethodMetadata和方法的入參,構造出一個RequestTemplate,RequestTemplate封裝了Http請求的參數,在這個過程中,如果有請求體,那么會通過Encoder序列化
  • 然后調用RequestInterceptor,通過RequestInterceptor對RequestTemplate進行攔截擴展,可以對請求數據再進行修改
  • 再然后將RequestTemplate轉換成Request,Request其實跟RequestTemplate差不多,也是封裝了Http請求的參數
  • 接下來通過Client去根據Request中封裝的Http請求參數,發送Http請求,得到響應Response
  • 最后根據Decoder,將響應體反序列化成方法返回值類型對象,返回

這就是Feign一次Http調用的執行過程

如果有設置重試,那么也是在這個階段生效的

SpringCloud是如何整合Feign的?

SpringCloud在整合Feign的時候,主要是分為兩部分

  • 核心組件重新實現,支持更多SpringCloud生態相關的功能
  • 將接口動態代理對象注入到Spring容器中

第一部分核心組件重新實現前面已經都說過了,這里就不再重復了

至于第二部分我們就來好好講一講,Spring是如何將接口動態代理對象注入到Spring容器中的

1、將FeignClient接口注冊到Spring中

使用OpenFeign時,必須加上@EnableFeignClients

這個注解就是OpenFeign的發動機

圖片圖片

@EnableFeignClients最后通過@Import注解導入了一個FeignClientsRegistrar

圖片圖片

FeignClientsRegistrar實現了ImportBeanDefinitionRegistrar

所以最終Spring在啟動的時候會調用registerBeanDefinitions方法實現

之所以會調用registerBeanDefinitions方法,是@Import注解的作用,不清楚的同學可以看一下扒一扒Bean注入到Spring的那些姿勢,你會幾種?

圖片圖片

最終會走到registerFeignClients這個方法

這個方法雖然比較長,主要是干了下面這個2件事:

第一件事,掃描@EnableFeignClients所在類的包及其子包(如果有指定包就掃指定包),找出所有加了@FeignClient注解的接口,生成一堆BeanDefinition

這個BeanDefinition包含了這個接口的信息等信息

第二件事,將掃描到的這些接口注冊到Spring容器中

圖片圖片

在注冊的時候,并非直接注冊接口類型,而是FeignClientFactoryBean類型

圖片圖片

好了,到這整個@EnableFeignClients啟動過程就結束了

雖然上面寫的很長,但是整個@EnableFeignClients其實也就只干了一件核心的事

掃描到所有的加了@FeignClient注解的接口

然后為每個接口生成一個Bean類型為FeignClientFactoryBean的BeanDefinition

最終注冊到Spring容器中

圖片圖片

2、FeignClientFactoryBean的秘密

上一節說到,每個接口都對應一個class類型為FeignClientFactoryBean的BeanDefinition

圖片圖片

如上所示,FeignClientFactoryBean是一個FactoryBean

并且FeignClientFactoryBean的這些屬性,是在生成BeanDefinition的時候設置的

圖片圖片

并且這個type屬性就是代表的接口類型

由于實現了FactoryBean,所以Spring啟動過程中,一定為會調用getObject方法獲取真正的Bean對象

FactoryBean的作用就不說了,不清楚的小伙伴還是可以看看扒一扒Bean注入到Spring的那些姿勢,你會幾種?這篇文章

getObject最終會走到getTarget()方法

圖片圖片

從如上代碼其實可以看出來,最終還是會通過Feign.builder()來創建動態代理對象

只不過不同的是,SpringCloud會替換Feign默認的組件,改成自己實現的

總的來說,Spring是通過FactoryBean的這種方式,將Feign動態代理對象添加到Spring容器中

OpenFeign的各種配置方式以及對應優先級

既然Feign核心組件可以替換,那么在SpringCloud環境下,我們該如何去配置自己的組件呢?

不過在說配置之前,先說一下FeignClient配置隔離操作

在SpringCloud環境下,為了讓每個不同的FeignClient接口配置相互隔離

在應用啟動的時候,會為每個FeignClient接口創建一個Spring容器,接下來我就把這個容器稱為FeignClient容器

這些FeignClient的Spring容器有一個相同的父容器,那就是項目啟動時創建的容器

圖片圖片

SpringCloud會給每個FeignClient容器添加一個默認的配置類FeignClientsConfiguration配置類

圖片圖片

這個配置類就聲明了各種Feign的組件

圖片圖片

所以,默認情況下,OpenFeign就使用這些配置的組件構建代理對象

知道配置隔離之后,接下來看看具體的幾種方式配置以及它們之間的優先級關系

1、通過@EnableFeignClients注解的defaultConfiguration屬性配置

舉個例子,比如我自己手動聲明一個Contract對象,類型為MyContract

public class FeignConfiguration {
    
    @Bean
    public Contract contract(){
        return new MyContract();
    }
    
}

注意注意,這里FeignConfiguration我沒加@Configuration注解,原因后面再說

此時配置如下所示:

@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)

之后這個配置類會被加到每個FeignClient容器中,所以這個配置是對所有的FeignClient生效

并且優先級大于默認配置的優先級

比如這個例子就會使得FeignClient使用我聲明的MyContract,而不是FeignClientsConfiguration中聲明的SpringMvcContract

2、通過@FeignClient注解的configuration屬性配置

還以上面的FeignConfiguration配置類舉例,可以通過@FeignClient注解配置

@FeignClient(name = "order", configuration = FeignConfiguration.class)

此時這個配置類會被加到自己FeignClient容器中,注意是自己FeignClient容器

所以這種配置的作用范圍是自己的這個FeignClient

并且這種配置的優先級是大于@EnableFeignClients注解配置的優先級

3、在項目啟動的容器中配置

前面提到,由于所有的FeignClient容器的父容器都是項目啟動的容器

所以可以將配置放在這個項目啟動的容器中

還以FeignConfiguration為例,加上@Configuration注解,讓項目啟動的容器的掃描到就成功配置了

這種配置的優先級大于前面提到的所有配置優先級

并且是對所有的FeignClient生效

所以,這就是為什么使用注解配置時為什么配置類不能加@Configuration注解的原因,因為一旦被項目啟動的容器掃描到,這個配置就會作用于所有的FeignClient,并且優先級是最高的,就會導致你其它的配置失效,當然你也可以加@Configuration注解,但是一定不能被項目啟動的容器掃到

4、配置文件

除了上面3種編碼方式配置,OpenFeign也是支持通過配置文件的方式進行配置

并且也同時支持對所有FeignClient生效和對單獨某個FeignClient生效

對所有FeignClient生效配置:

feign:
  client:
    config:
      default: # default 代表對全局生效
        contract: com.sanyou.feign.MyContract

對單獨某個FeignClient生效配置:

feign:
  client:
    config:
      order: # 具體的服務名
        contract: com.sanyou.feign.MyContract

在默認情況下,這種配置文件方式優先級最高

但是如果你在配置文件中將配置項feign.client.default-to-properties設置成false的話,配置文件的方式優先級就是最低了

feign:
  client:
    default-to-properties: false

小總結

這一節,總共總結了4種配置OpenFeign的方式以及它們優先級和作用范圍

畫張圖來總結一下

圖片圖片

如果你在具體使用的時候,還是遇到了一些優先級的問題,可以debug這部分源碼,看看到底生效的是哪個配置


圖片圖片

圖片

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

2023-10-16 22:07:20

Spring配置中心Bean

2024-01-02 22:47:47

Nacos注冊中心節點

2023-11-30 22:06:43

2024-07-08 23:03:13

2022-01-14 12:28:18

架構OpenFeign遠程

2010-08-18 10:13:55

IntentAndroid

2009-06-15 15:57:21

Spring工作原理

2020-12-04 06:37:19

HTTPS原理安全

2009-08-25 13:48:01

Java EE架構企業級應用

2025-01-10 09:47:43

blockSDKiOS

2024-02-26 00:00:00

Nginx服務器HTTP

2023-12-05 17:44:24

reactor網絡

2010-01-27 17:38:58

Windows Emb

2010-03-12 17:09:18

2019-12-12 10:56:00

微服務微服務架構架構

2023-06-07 15:25:19

Kafka版本日志

2025-02-08 08:10:00

2024-01-05 07:55:39

Linux虛擬內存

2022-01-05 14:30:44

容器Linux網絡

2024-08-07 08:19:13

點贊
收藏

51CTO技術棧公眾號

欧洲成人av| 在线免费观看av网| 一级特黄aaaaaa大片| 亚洲精品一二三区区别| 欧美日韩中文国产| 蜜桃成人免费视频| 夜夜狠狠擅视频| 伊人成人在线视频| 国产一区二区三区网站| 99九九精品视频| 日本午夜大片a在线观看| 成人激情综合网站| 国产精品91久久久| 懂色av懂色av粉嫩av| 亚洲区小说区图片区qvod按摩| 欧美性猛xxx| 国产精品夜夜夜爽张柏芝| 中文字幕在线观看视频一区| 最新亚洲激情| 久久手机免费视频| 欧美特黄一区二区三区| 国模私拍国内精品国内av| 亚洲精品中文字幕在线观看| 欧洲精品久久| 亚洲自拍偷拍另类| 久久aⅴ国产紧身牛仔裤| 九九精品视频在线| 久久久国产一级片| 欧美激情在线免费| 亚洲精品在线观看视频| www.久久久久久久久久久| segui88久久综合| 亚洲精品伦理在线| 一区国产精品| 高清av在线| 久久夜色精品国产噜噜av| 国产精品高清一区二区三区| 亚洲专区第一页| 蜜臀av性久久久久蜜臀aⅴ流畅| 97国产成人精品视频| 日本少妇高清视频| 日韩欧美二区| 中文字幕综合在线| 国产sm在线观看| 国产高清视频一区二区| 欧美日韩在线不卡| 蜜臀av免费观看| 亚洲第一图区| 国产精品二三区| 日本成人黄色| av小片在线| 久久精品免费在线观看| 精品蜜桃传媒| 搡老岳熟女国产熟妇| 不卡在线视频中文字幕| 成人av网站观看| 亚洲国产精品一| 国产精品一区二区不卡| 99re国产视频| 欧美自拍偷拍第一页| 成人a区在线观看| 国产自产在线视频一区| 国产色视频在线| 国产高清在线观看免费不卡| av观看久久| 人妻夜夜爽天天爽| 久久综合色天天久久综合图片| 蜜桃999成人看片在线观看| 韩日视频在线| 国产精品高潮久久久久无| 国产四区在线观看| 日本中文字幕在线视频| 中文字幕不卡在线| 男女啪啪的视频| 91网在线看| 天天影视色香欲综合网老头| 国产av麻豆mag剧集| 成人影院av| 欧美区一区二区三区| 女同性αv亚洲女同志| 不卡精品视频| 精品国产a毛片| 国产又粗又长又爽| 日韩黄色大片| 中文字幕综合一区| 久久黄色免费网站| 欧美日一区二区在线观看| 欧美疯狂xxxx大交乱88av| 国产一级片免费观看| 羞羞视频在线观看欧美| 庆余年2免费日韩剧观看大牛| 337p粉嫩色噜噜噜大肥臀| 国产在线一区二区| 99视频在线| 手机av在线免费观看| 欧美国产亚洲另类动漫| 精品人妻人人做人人爽| 免费观看亚洲| 91麻豆精品国产91久久久久久久久| 亚洲国产精品第一页| 欧美精品羞羞答答| 欧美高清在线视频观看不卡| 在线观看污污网站| 国产一区亚洲一区| 欧美日韩免费高清| 天堂va在线| 日韩欧美成人网| 少妇愉情理伦片bd| 亚洲精品国产九九九| 精品亚洲男同gayvideo网站| 一级肉体全黄裸片| 影音先锋久久资源网| 国产精品视频成人| 天堂av电影在线观看| 亚洲欧美在线视频观看| 青青在线视频免费观看| 亚洲成人va| 亚洲精品国产精品国自产观看浪潮| www.99re6| 制服诱惑一区二区| 亚洲va男人天堂| 第九色区av在线| 欧美日韩国产精品一区| 男人午夜视频在线观看| 成人黄色av| 2019中文在线观看| www久久久久久| 亚洲欧美一区二区在线观看| 激情婷婷综合网| 牛牛影视一区二区三区免费看| 精品国产一区二区三区久久狼5月 精品国产一区二区三区久久久狼 精品国产一区二区三区久久久 | 五月天婷婷色综合| 日韩精彩视频在线观看| 国产欧美一区二区在线播放| 国产一区久久精品| 欧美三级在线播放| 一起草在线视频| 亚洲激情视频| 成人永久免费| 影音先锋男人资源在线| 91精品国产免费久久综合| 日本污视频网站| 国产精品一区亚洲| 国产欧美一区二区在线播放| av软件在线观看| 在线成人午夜影院| 国产精品精品软件男同| 精品一区二区三区免费播放| 欧美激情视频一区二区三区| 国产精欧美一区二区三区蓝颜男同| 亚洲精品久久久久| 91av在线免费视频| 成人h版在线观看| 欧美日韩二三区| 自拍亚洲一区| 国产精品久久婷婷六月丁香| 青青草娱乐在线| 婷婷综合五月天| 青青草视频成人| 在线日本高清免费不卡| 久久爱av电影| 日韩pacopacomama| 亚洲男人天堂网站| 999视频在线| 久久在线观看免费| 99色精品视频| 日韩精品一区二区久久| 亚洲www视频| 国产精品久久麻豆| 日韩三级视频在线观看| 久久久久久久久艹| 成人激情免费网站| 2022亚洲天堂| 久久日文中文字幕乱码| 1卡2卡3卡精品视频| 91桃色在线| 亚洲网站在线观看| 在线观看一二三区| 亚洲你懂的在线视频| 亚洲成人精品在线播放| 影音先锋久久久| 色一情一区二区三区四区| 日本亚洲欧洲无免费码在线| 久久久久久久999| 邻居大乳一区二区三区| 555www色欧美视频| 午夜毛片在线观看| 亚洲国产成人在线| 中文字幕三级电影| 美女mm1313爽爽久久久蜜臀| 异国色恋浪漫潭| 亚洲老女人视频免费| 国产精品久久久久久久久久| 人交獸av完整版在线观看| 亚洲欧美国产日韩天堂区| 在线视频1卡二卡三卡| 中文字幕一区二区不卡| 国产精品久久无码| 国内精品久久久久影院色| 91好吊色国产欧美日韩在线| 精品国产中文字幕第一页 | 风间由美性色一区二区三区四区 | 天天爽天天爽夜夜爽| 国产精品一区高清| av一区和二区| 国产一区精品福利| 欧美自拍大量在线观看| av亚洲在线| 日韩极品精品视频免费观看| 国产精品色综合| 欧美视频一区二区三区…| 日本黄色免费片| 久久久久久久免费视频了| 亚洲妇女无套内射精| 日韩综合小视频| 日本国产在线播放| 欧美高清不卡| 亚洲一区在线直播| 99热这里只有精品首页 | 国产精品久久久久9999小说| 欧美日韩一区自拍| 国产奶头好大揉着好爽视频| 日韩精品二区| 四虎永久国产精品| 免费观看久久av| 久久99精品久久久久久久青青日本 | 四虎精品在线| 亚洲精品国产综合区久久久久久久| 国产人妖一区二区| 欧美日韩第一区日日骚| www.毛片.com| 午夜精品在线视频一区| 亚洲国产精品免费在线观看| 国产精品久久久久国产精品日日| 微拍福利一区二区| 国产偷国产偷精品高清尤物| 91中文字幕永久在线| va亚洲va日韩不卡在线观看| 小日子的在线观看免费第8集| 久久免费高清| 国产第一页视频| 午夜在线精品偷拍| 日本久久久精品视频| 国产欧美二区| 国产一区二区网| 亚洲欧美日本日韩| 蜜臀av午夜一区二区三区| 久久亚洲欧洲| 亚洲狼人综合干| 日av在线不卡| 九九热99视频| 国产美女精品人人做人人爽| 成年人黄色片视频| 日韩电影一二三区| 久久99999| 精品中文字幕一区二区| www.日日操| 久久九九电影| 亚洲免费一级视频| 免费视频一区| 69久久久久久| 国产乱理伦片在线观看夜一区| 4438x全国最大成人| 成人av资源在线| 午夜久久久久久久| 久久免费偷拍视频| 五月天免费网站| 亚洲丝袜美腿综合| 国产精品第一页在线观看| 亚洲第一狼人社区| 精品91久久久| 疯狂做受xxxx高潮欧美日本 | 1区2区3区在线观看| 日韩一区二区欧美| av片在线观看永久免费| 欧美尺度大的性做爰视频| 老司机福利在线视频| 久久av中文字幕| 欧美高清另类hdvideosexjaⅴ | 精品美女一区| 99在线看视频| 日本韩国欧美超级黄在线观看| 国产亚洲一区在线播放| 欧美影院三区| 国产成人亚洲综合无码| 国产精品久久久一区二区| 999精品视频在线| 成人黄色国产精品网站大全在线免费观看| 波多野结衣福利| 亚洲摸摸操操av| 亚洲毛片一区二区三区| 欧美一区二区在线免费播放| 天堂91在线| 欧美床上激情在线观看| 欧美成人精品三级网站| 奇米一区二区三区四区久久| 亚洲欧美在线综合| 玛丽玛丽电影原版免费观看1977 | |精品福利一区二区三区| 国产精久久久久久| 欧美日韩一区小说| 国产精品99久久久久久久| 99超碰在线观看| 一区二区激情小说| 成年人晚上看的视频| 精品国产凹凸成av人导航| √天堂资源地址在线官网| 国内外成人免费激情在线视频| 99久久婷婷国产综合精品首页| 国产日韩专区在线| 丝袜美腿综合| 99国产精品白浆在线观看免费| 日韩精品一级二级| 久久精品一卡二卡| 久久精品人人做人人爽97| 久久综合加勒比| 欧美精品日韩一本| 国产精品久久一区二区三区不卡| 久久综合免费视频| 一区在线影院| 欧美日韩喷水| 国产伦理一区| 中文字幕第10页| 最好看的中文字幕久久| 久久影视中文字幕| 日韩不卡中文字幕| a'aaa级片在线观看| 91一区二区三区| 精品日韩一区| 亚洲自偷自拍熟女另类| 成人免费毛片嘿嘿连载视频| 欧美日韩色视频| 欧美高清视频一二三区 | 成人做爰视频www网站小优视频| 97碰碰视频| 欧美国产高清| 小早川怜子一区二区三区| 中文欧美字幕免费| 久久精品视频2| 亚洲日韩欧美视频| 欧美男女交配| 久久人人九九| 亚洲一区中文| 亚洲久久久久久| 欧美日韩激情网| 精品人妻一区二区三区含羞草 | 日韩视频专区| 日韩成人一级片| 老熟妇精品一区二区三区| 午夜久久电影网| 亚洲三区在线播放| 久久成年人免费电影| 超碰成人免费| 成人在线观看你懂的| 99久久99久久精品国产片果冻| 91蜜桃视频在线观看| 亚洲精品国产精品国产自| 无码小电影在线观看网站免费| 久久精品国产精品国产精品污 | 欧美一区二区影院| 国产成人精品免费视| 999香蕉视频| 国产精品久久久久影院亚瑟 | 日韩成人免费在线观看| 日韩国产欧美精品在线| 日韩免费va| 中文字幕日韩一区二区三区不卡| 国产精品资源在线看| 日韩成人在线免费视频| 亚洲欧洲午夜一线一品| 日本亚洲欧洲无免费码在线| 4444在线观看| av日韩在线网站| 高潮毛片又色又爽免费| 在线观看久久av| 高清久久一区| a√天堂在线观看| 综合av第一页| 色综合视频在线| 国产精品久久一区主播| 欧美黄色一区| 91中文字幕永久在线| 91麻豆精品国产无毒不卡在线观看| 国产盗摄精品一区二区酒店| eeuss一区二区三区| 久久一区欧美| 男人操女人的视频网站| 亚洲欧美在线一区二区| 岛国精品在线| 97视频在线免费| 久久网这里都是精品| 国产又粗又猛视频| 久久69精品久久久久久国产越南| 老牛精品亚洲成av人片| 亚洲综合色在线观看| 亚洲在线成人精品| 888av在线| 看欧美日韩国产| 国产高清成人在线| 真实的国产乱xxxx在线91|