日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringCloud OpenFeign 远程HTTP服务调用用法与原理

發(fā)布時間:2024/9/30 javascript 77 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringCloud OpenFeign 远程HTTP服务调用用法与原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

????????在 openFeign 未出現(xiàn)前,Spring 提供了 RestTemplate 作為遠程服務調(diào)用的客戶端,提供了多種便捷訪問遠程 Http 服務的方法,能夠大大提高客戶端的編寫效率。由于文章內(nèi)容會使用到 RestTemplate,所以這里就簡單說下。

????????一講到服務調(diào)用,我們肯定會聯(lián)想到服務的路由與負載均衡,那么我們接下來就先介紹兩種客戶端的服務負載均衡組件:LoadBalancerClient 與 Ribbon

一、SpringCloud的客戶端負載均衡:

1、客戶端負載均衡:

????????負載均衡分為客戶端負載均衡和服務端負載均衡,它們之間的區(qū)別在于:服務清單所在的位置。

????????我們通常說的負載均衡都是服務端的負載均衡,其中可以分為硬件的負載均衡和軟件負載均衡:硬件的負載均衡就是在服務器節(jié)點之間安裝用于負載均衡的設備,比如F5;軟件負載均衡則是在服務器上安裝一些具有負載均衡功能的模塊或軟件來完成請求分發(fā)的工作,比如nginx。服務端的負載均衡會在服務端維護一個服務清單,然后通過心跳檢測來剔除故障節(jié)點以保證服務清單中的節(jié)點都正常可用。

????????客戶端負載均衡指客戶端都維護著自己要訪問的服務端實例清單,而這些服務端清單來自服務注冊中心。客戶端負載均衡也需要心跳檢測維護清單服務的健康性,只不過這個工作要和服務注冊中心配合完成。

2、LoadBalancerClient:

????????LoadBalancerClient 是 SpringCloud 提供的一種負載均衡客戶端,LoadBalancerClient 在初始化時會通過 Eureka Client 向 Eureka 服務端獲取所有服務實例的注冊信息并緩存在本地,并且每10秒向 EurekaClient 發(fā)送“ ping ”,來判斷服務的可用性。如果服務的可用性發(fā)生了改變或者服務數(shù)量和之前的不一致,則更新或者重新拉取。最后,在得到服務注冊列表信息后,ILoadBalancer 根據(jù) IRule 的策略進行負載均衡(默認策略為輪詢)。

????????當使用 LoadBalancerClient 進行遠程調(diào)用的負載均衡時,LoadBalancerClient 先通過目標服務名在本地服務注冊清單中獲取服務提供方的某一個實例,比如訂單服務需要訪問商品服務,商品服務有3個節(jié)點,LoadBalancerClient 會通過 choose() 方法獲取到3個節(jié)點中的一個服務,拿到服務的信息之后取出服務IP信息,就可以得到完整的想要訪問的IP地址和接口,最后通過 RestTempate 訪問商品服務。

2.1、springboot + LoadBalancerClient 負載均衡調(diào)用:

注:本案例需要 springboot 提前整合 nacos 作為注冊中心,但是 nacos 并非本文的重點,此處就不重點介紹,對 nacos 注冊中心有疑惑的讀者請移步這篇文章:Nacos注冊中心的部署與用法詳細介紹

2.1.1、服務提供方代碼:

//nacos注冊中心的服務名:cloud-producer-server//兩數(shù)求和@PostMapping ("getSum")public String getSum(@RequestParam (value = "num1") Integer num1, @RequestParam (value = "num2") Integer num2){return "兩數(shù)求和結果=" + (num1 + num2);}

2.1.2、服務消費方代碼:

(1)指定服務,通過 LoadBalancerClient 自動獲取某個服務實例與請求地址

@Component public class LoadBalancerUtil {// 注入LoadBalancerClient@AutowiredLoadBalancerClient loadBalancerClient;/*** 通過 LoadBalancer 獲取提供服務的host與ip*/public String getService(String serviceId){//獲取實例服務中的某一個服務ServiceInstance instance = loadBalancerClient.choose(serviceId);//獲取服務的ip地址和端口號String host = instance.getHost();int port = instance.getPort();//格式化最終的訪問地址return String.format("http://%s:%s", host, port);} }

(2)通過 RestTemplate 請求遠程服務地址并接收返回值:

@RestController @RequestMapping (value = "api/invoke") public class InvokeController { @Autowiredprivate LoadBalancerUtil loadBalancerUtil;/*** 使用 SpringCloud 的負載均衡策略組件 LoadBalancerClient 進行遠程服務調(diào)用*/@GetMapping ("getByLoadBalancer")public String getByLoadBalancer(Integer num1, Integer num2){String hostAndIp = loadBalancerUtil.getService("cloud-producer-server");//打印服務的請求地址與端口,方便測試負載功能System.out.println(hostAndIp);String url = hostAndIp + "/cloud-producer-server/getSum";MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("num1", num1);params.add("num2", num2);RestTemplate restTemplate = new RestTemplate();String result = restTemplate.postForObject(url, params, String.class);return result;} }

????????多次訪問服務消費方的 api/invoke/getByLoadBalancer 接口,并且通過打印出來的 hostAndIp 信息,可以看出 LoadBalancerClient 是輪詢調(diào)用服務提供方的,這也是 LoadBalancerClient 的默認負載均衡策略

2.2、LoadBalancerClient 原理:

LoadBalancerClient 的原理請讀者移步這篇文章:SpringCloud LoadBalancerClient 負載均衡原理

3、ribbon:

????????Ribbon 負載組件的內(nèi)部就是集成了 LoadBalancerClient 負載均衡客戶端,所以 Ribbon 負載均衡的原理本質(zhì)也跟上面介紹的 LoadBalancerClient 原理一致,負載均衡器 Ribbon 默認會通過 Eureka Client 向 Eureka 服務端的服務注冊列表中獲取服務的信息,并緩存一份在本地 JVM 中,根據(jù)緩存的服務注冊列表信息,可以通過 LoadBalancerClient 來選擇不同的服務實例,從而實現(xiàn)負載均衡。

????????基本用法就是注入一個 RestTemplate,并使用 @LoadBalance 注解標注 RestTemplate,從而使 RestTemplate 具備負載均衡的能力。當 Spring 容器啟動時,使用 @LoadBalanced 注解修飾的 RestTemplate 會被添加攔截器 LoadBalancerInterceptor,攔截器會攔截 RestTemplate 發(fā)送的請求,轉(zhuǎn)而執(zhí)行 LoadBalancerInterceptor 中的 intercept() 方法,并在 intercept() 方法中使用 LoadBalancerClient 處理請求,從而達到負載均衡的目的。

????????那么 RestTemplate 添加 @LoadBalanced 注解后,為什么會被攔截呢?這是因為 LoadBalancerAutoConfiguration 類維護了一個被 @LoadBalanced 修飾的 RestTemplate 列表,在初始化過程中,通過調(diào)用 customizer.customize(restTemplate) 方法為 RestTemplate 添加了 LoadBalancerInterceptor 攔截器,該攔截器中的方法將遠程服務調(diào)用的方法交給了 LoadBalancerClient 去處理,從而達到了負載均衡的目的。

3.1、springboot + Ribbon 負載均衡調(diào)用:

通過 Spring Cloud Ribbon 的封裝,我們在微服務架構中使用客戶端負載均衡非常簡單,只需要兩步:

  • ① 服務提供者啟動服務實例并注冊到服務注冊中心
  • ② 服務消費者直接使用被 @LoadBalanced 注解修飾的 RestTemplate 來實現(xiàn)面向服務的接口調(diào)用

3.1.1、服務提供方代碼:

//nacos注冊中心的服務名:cloud-producer-server//兩數(shù)求和@PostMapping ("getSum")public String getSum(@RequestParam (value = "num1") Integer num1, @RequestParam (value = "num2") Integer num2){return "兩數(shù)求和結果=" + (num1 + num2);}

3.1.2、服務消費方代碼:

(1)使用 @LoadBalanced 注解修飾的 RestTemplate:

@LoadBalanced 注解用于開啟負載均衡,標記 RestTemplate 使用 LoadBalancerClient 配置

import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;@Configuration public class RestConfig {/*** 創(chuàng)建restTemplate對象。* LoadBalanced注解表示賦予restTemplate使用Ribbon的負載均衡的能力(一定要加上注解,否則無法遠程調(diào)用)*/@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();} }

(2)通過 RestTemplate 請求遠程服務地址并接收返回值

@RestController @RequestMapping (value = "api/invoke") public class InvokeController {@Autowiredprivate RestTemplate restTemplate;/*** 使用 RestTemplate 進行遠程服務調(diào)用,并且使用 Ribbon 進行負載均衡*/@ApiOperation (value = "RestTemplate", notes = "使用RestTemplate進行遠程服務調(diào)用,并使用Ribbon進行負載均衡")@GetMapping ("getByRestTemplate")public String getByRestTemplate(Integer num1, Integer num2){//第一個cloud-producer-server代表在nacos注冊中心中的服務名,第二個cloud-producer-server代表contextPath配置的項目路徑String url = "http://cloud-producer-server/cloud-producer-server/getSum";MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("num1", num1);params.add("num2", num2);//通過服務名的方式調(diào)用遠程服務(非ip端口)return restTemplate.postForObject(url, params, String.class);} }

????????默認情況下,Ribbon 也是使用輪詢作為負載均衡策略,那么處理輪詢策略,Ribbon 還有哪些負載均衡策略呢?

3.2、Ribbon 的七種負載均衡策略:

????????我們打開 com.netflix.loadbalancer.IRule 接口,該接口的實現(xiàn)類主要用于定義負載均衡策略,我們找到它所有的實現(xiàn)類,如下:

?(1)隨機策略 RandomRule:隨機數(shù)選擇服務列表中的服務節(jié)點Server,如果當前節(jié)點不可用,則進入下一輪隨機策略,直到選到可用服務節(jié)點為止

(2)輪詢策略 RoundRobinRule:按照接收的請求順序,逐一分配到不同的后端服務器

(3)重試策略 RetryRule:在選定的負載均衡策略機上重試機制,在一個配置時間段內(nèi)當選擇Server不成功,則一直嘗試使用 subRule 的方式選擇一個可用的server;

(4)可用過濾策略 PredicateBaseRule:過濾掉連接失敗 和 高并發(fā)連接 的服務節(jié)點,然后從健康的服務節(jié)點中以線性輪詢的方式選出一個節(jié)點返回

(5)響應時間權重策略 WeightedRespinseTimeRule:根據(jù)服務器的響應時間分配一個權重weight,響應時間越長,weight越小,被選中的可能性越低。主要通過后臺線程定期地從 status 里面讀取平均響應時間,為每個 server 計算一個 weight

(6)并發(fā)量最小可用策略 BestAvailableRule:選擇一個并發(fā)量最小的服務節(jié)點 server。ServerStats 的 activeRequestCount 屬性記錄了 server 的并發(fā)量,輪詢所有的server,選擇其中 activeRequestCount 最小的那個server,就是并發(fā)量最小的服務節(jié)點。該策略的優(yōu)點是可以充分考慮每臺服務節(jié)點的負載,把請求打到負載壓力最小的服務節(jié)點上。但是缺點是需要輪詢所有的服務節(jié)點,如果集群數(shù)量太大,那么就會比較耗時。

(7)區(qū)域權重策略 ZoneAvoidanceRule:綜合判斷 server 所在區(qū)域的性能 和 server 的可用性,使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 來判斷是否選擇某個server,前一個判斷判定一個zone的運行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate 用于過濾掉連接數(shù)過多的Server。

二、什么是openFeign:

????????微服務架構中,由于對服務粒度的拆分致使服務數(shù)量變多,而作為 Web 服務的調(diào)用端方,除了需要熟悉各種 Http 客戶端,比如 okHttp、HttpClient 組件的使用,而且還要顯式地序列化和反序列化請求和響應內(nèi)容,從而導致出現(xiàn)很多樣板代碼,開發(fā)起來很痛苦。為了解決這個問題,Feign 誕生了,那么 Feign 是什么呢?

????????Feign 就是一個 Http 客戶端的模板,目標是減少 HTTP API 的復雜性,希望能將 HTTP 遠程服務調(diào)用做到像 RPC 一樣易用。Feign 集成 RestTemplate、Ribbon 實現(xiàn)了客戶端的負載均衡的 Http 調(diào)用,并對原調(diào)用方式進行了封裝,使得開發(fā)者不必手動使用 RestTemplate 調(diào)用服務,而是聲明一個接口,并在這個接口中標注一個注解即可完成服務調(diào)用,這樣更加符合面向接口編程的宗旨,客戶端在調(diào)用服務端時也不需要再關注請求的方式、地址以及是 forObject 還是 forEntity,結構更加明了,耦合也更低,簡化了開發(fā)。但 Feign 已經(jīng)停止迭代了,所以本篇文章我們也不過多的介紹,而在 Feign 的基礎上,又衍生出了 openFeign,那么 openFeign 又是什么呢?

????????openFeign 在 Feign 的基礎上支持了 SpringMVC 的注解,如 @RequestMapping 等。OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通過動態(tài)代理的方式產(chǎn)生實現(xiàn)類,實現(xiàn)類中做負載均衡并調(diào)用其他服務。

????????總的就是,openFeign 作為微服務架構下服務間調(diào)用的解決方案,是一種聲明式、模板化的 HTTP 的模板,使 HTTP 請求就像調(diào)用本地方法一樣,通過 openFeign 可以替代基于 RestTemplate 的遠程服務調(diào)用,并且默認集成了 Ribbon 進行負載均衡。

openFeign 與 Ribbon 的聯(lián)系:https://www.cnblogs.com/unchain/p/13405814.html

三、Springboot 整合 openFeign:

?注:本案例需要 springboot 提前整合 nacos 作為注冊中心,但是 nacos 并非本文的重點,此處就不重點介紹,對 nacos 注冊中心有疑惑的讀者請移步這篇文章:Nacos注冊中心的部署與用法詳細介紹

1、創(chuàng)建服務提供者 provider:

(1)項目配置:

# 服務在nacos中的服務名 spring.application.name = openFeign-provider# nacos注冊中心配置 nacos.url = 120.76.129.106:80 nacos.namespace = 856a40d7-6548-4494-bdb9-c44491865f63 spring.cloud.nacos.discovery.server-addr = ${nacos.url} spring.cloud.nacos.discovery.namespace = ${nacos.namespace} spring.cloud.nacos.discovery.register-enabled = true

注意:此處的 spring.application.name 指定的名稱將會在 openFeign 接口調(diào)用中使用。

2、創(chuàng)建服務消費者 consumer:

(1)引入 openFeign 相關依賴

<!-- 引入openFeign進行遠程服務調(diào)用 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

(2)開啟 openFeign 功能:

在 Springboot 應用的主啟動類上使用注解 @EnableFeignClients 開啟 openFeign 功能,如下:

import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients;/*** SpringBoot啟動類:* EnableFeignClients:啟動OpenFeign客戶端* EnableDiscoveryClient:啟動服務發(fā)現(xiàn)*/ @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication @MapperScan(basePackages = "com.eebbk.*.dao") public class ConsumerApplication {public static void main(String[] args){SpringApplication.run(ConsumerApplication.class, args);} }

(3)新建 FeignClient 接口:

新建一個 openFeign 接口,使用 @FeignClient 注解標注,如下:

@FeignClient(value = "openFeign-provider") public interface OpenFeignService { }

注意:注解 @FeignClient 中的 value 屬性指定了服務提供者在 nacos 注冊中心的服務名

(4)新建 Controller 調(diào)試:

新建一個controller用來調(diào)試接口,直接調(diào)用openFeign的接口,如下:

@RestController @RequestMapping("/openfeign") public class OpenFeignController { }

好了,至此一個openFeign的微服務就搭建好了,并未實現(xiàn)具體的功能,下面一點點實現(xiàn)。

3、openFeign 的傳參:

????????開發(fā)中接口傳參的方式有很多,但是在 openFeign 中的傳參是有一定規(guī)則的,下面詳細介紹四種常見的傳參方式。

3.1、傳遞JSON數(shù)據(jù):

provider 接口中 JSON 傳參方法如下:

@RestController @RequestMapping("/openfeign/provider") public class OpenFeignProviderController {@PostMapping("/order2")public Order createOrder2(@RequestBody Order order){return order;} }

consumer消費者openFeign代碼如下:

@FeignClient(value = "openFeign-provider") public interface OpenFeignService {/*** 參數(shù)默認是@RequestBody標注的,這里的@RequestBody可以不填* 方法名稱任意*/@PostMapping("/openfeign/provider/order2")Order createOrder2(@RequestBody Order order); }

注意:openFeign 默認的傳參方式就是JSON傳參(@RequestBody),因此定義接口的時候可以不用@RequestBody注解標注,不過為了規(guī)范,一般都填上。

3.2、POJO表單傳參:

provider服務提供者代碼如下:

@RestController @RequestMapping("/openfeign/provider") public class OpenFeignProviderController {@PostMapping("/order1")public Order createOrder1(Order order){return order;} }

consumer消費者openFeign代碼如下:

@FeignClient(value = "openFeign-provider") public interface OpenFeignService {/*** 如果通過POJO表單傳參的,使用@SpringQueryMap標注*/@PostMapping("/openfeign/provider/order1")Order createOrder1(@SpringQueryMap Order order); }

3.3、URL中攜帶參數(shù):

此種方式針對restful方式中的GET請求,也是比較常用請求方式。

provider服務提供者代碼如下:

@RestController @RequestMapping("/openfeign/provider") public class OpenFeignProviderController {@GetMapping("/test/{id}")public String test(@PathVariable("id")Integer id){return "accept one msg id="+id; }

consumer消費者openFeign接口如下:

@FeignClient(value = "openFeign-provider") public interface OpenFeignService {@GetMapping("/openfeign/provider/test/{id}")String get(@PathVariable("id")Integer id); }

使用注解 @PathVariable 接收url中的占位符,這種方式很好理解。

3.4、普通表單參數(shù):

此種方式傳參不建議使用,但是也有很多開發(fā)在用。

provider服務提供者代碼如下:

@RestController @RequestMapping("/openfeign/provider") public class OpenFeignProviderController {@PostMapping("/test2")public String test2(String id,String name){return MessageFormat.format("accept on msg id={0},name={1}",id,name);} }

consumer消費者openFeign接口傳參如下:

@FeignClient(value = "openFeign-provider") public interface OpenFeignService {/*** 必須要@RequestParam注解標注,且value屬性必須填上參數(shù)名* 方法參數(shù)名可以任意,但是@RequestParam注解中的value屬性必須和provider中的參數(shù)名相同*/@PostMapping("/openfeign/provider/test2")String test(@RequestParam("id") String arg1,@RequestParam("name") String arg2); }

4、設置超時時間:

想要理解超時處理,先看一個例子:我將provider服務接口睡眠3秒鐘,接口如下:

@PostMapping("/test2") public String test2(String id,String name) throws InterruptedException {Thread.sleep(3000);return MessageFormat.format("accept on msg id={0},name={1}",id,name); }

此時,我們調(diào)用consumer的openFeign接口返回結果如下圖的超時異常:

?????????openFeign 其實是有默認的超時時間的,默認分別是連接超時時間 10秒、讀超時時間 60秒,源碼在 feign.Request.Options#Options() 這個方法中,如下圖:

????????那么為什么我們只設置了睡眠3秒就報超時呢?其實 openFeign 集成了 Ribbon,Ribbon 的默認超時連接時間、讀超時時間都是是1秒,源碼在 org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer#execute() 方法中,如下圖:

????????源碼大致意思:如果openFeign沒有設置對應得超時時間,那么將會采用Ribbon的默認超時時間。理解了超時設置的原理,由之產(chǎn)生兩種方案也是很明了了,如下:

  • 設置openFeign的超時時間
  • 設置Ribbon的超時時間

4.1、設置Ribbon的超時時間(不推薦)

ribbon:# 值的是建立鏈接所用的時間,適用于網(wǎng)絡狀況正常的情況下, 兩端鏈接所用的時間ReadTimeout: 5000# 指的是建立鏈接后從服務器讀取可用資源所用的時間ConectTimeout: 5000

4.2、設置Ribbon的超時時間

openFeign設置超時時間非常簡單,只需要在配置文件中配置,如下:

feign:client:config:## default 設置的全局超時時間,指定服務名稱可以設置單個服務的超時時間default:connectTimeout: 5000readTimeout: 5000

????????default設置的是全局超時時間,對所有的openFeign接口服務都生效,但是正常的業(yè)務邏輯中可能有其實 openFeign 接口的調(diào)用需要單獨配置一個超時時間,比如下面我們就單獨給 serviceC 這個服務單獨配置了一個超時時間,單個配置的超時時間將會覆蓋全局配置:

feign:client:config:## default 設置的全局超時時間,指定服務名稱可以設置單個服務的超時時間default:connectTimeout: 5000readTimeout: 5000## 為serviceC這個服務單獨配置超時時間serviceC:connectTimeout: 30000readTimeout: 30000

5、替換的 HTTP 客戶端:

????????openFeign 默認使用的是 JDK 原生的 URLConnection 發(fā)送 HTTP 請求,沒有連接池,但是對每個地址會保持一個長連接,即利用 HTTP 的 persistence connection。在生產(chǎn)環(huán)境中,通常不使用默認的 http client,通常有兩種選擇:使用 ApacheHttpClient 或者 OkHttp,兩者各有千秋,下面我們演示下如何使用 ApacheHttpClient 替換原生的 http client

5.1、添加ApacheHttpClient依賴:

<!-- 使用 Apache HttpClient 替換 Feign原生httpclient--><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>

????????為什么要添加上面的依賴呢?從源碼中不難看出,請看org.springframework.cloud.openfeign.FeignAutoConfiguration.HttpClientFeignConfiguration 這個類,代碼如下: ?

????????上述紅色框中的生成條件,其中的 @ConditionalOnClass(ApacheHttpClient.class),必須要有 ApacheHttpClient 這個類才會生效,并且 feign.httpclient.enabled 這個配置要設置為 true。

5.2、配置文件中開啟:

在配置文件中要配置開啟,代碼如下:

feign:client:httpclient:# 開啟 Http Clientenabled: true

5.3、如何驗證?

????????其實很簡單,在 feign.SynchronousMethodHandler#executeAndDecode() 這個方法中可以清楚的看出調(diào)用哪個client,如下圖:

上圖中可以看到最終調(diào)用的是 ApacheHttpClient。

6、開啟日志增強:

????????openFeign 雖然提供了日志增強功能,但默認是不顯示任何日志的,不過開發(fā)者在調(diào)試階段可以自己配置日志的級別。

openFeign 的日志級別如下:

  • NONE:默認的,不顯示任何日志;
  • BASIC:僅記錄請求方法、URL、響應狀態(tài)碼及執(zhí)行時間;
  • HEADERS:除了BASIC中定義的信息之外,還有請求和響應的頭信息;
  • FULL:除了HEADERS中定義的信息之外,還有請求和響應的正文及元數(shù)據(jù)。

配置起來也很簡單,步驟如下:

6.1、配置類中配置日志級別

需要自定義一個配置類,在其中設置日志級別,如下:

注意:這里的logger是feign包里的。

6.2、yaml文件中設置接口日志級別:

logging:level:cn.myjszl.service: debug

????????這里的 cn.myjszl.service 是 openFeign 接口所在的包名,當然你也可以配置一個特定的openFeign接口。

6.3、效果演示

????????上述步驟將日志設置成了 FULL,此時發(fā)出請求,日志效果如下圖:

日志中詳細的打印出了請求頭、請求體的內(nèi)容。

7、通訊優(yōu)化:

在講如何優(yōu)化之前先來看一下GZIP 壓縮算法

7.1、GZIP壓縮算法:

????????gzip是一種數(shù)據(jù)格式,采用deflate算法壓縮數(shù)據(jù);當GZIP算法壓縮到一個純文本數(shù)據(jù)時,效果是非常明顯的,大約可以減少70%以上的數(shù)據(jù)大小。

????????網(wǎng)絡數(shù)據(jù)經(jīng)過壓縮后實際上降低了網(wǎng)絡傳輸?shù)淖止?jié)數(shù),最明顯的好處就是可以加快網(wǎng)頁加載的速度。網(wǎng)頁加載速度加快的好處不言而喻,除了節(jié)省流量,改善用戶的瀏覽體驗外,另一個潛在的好處是GZIP與搜索引擎的抓取工具有著更好的關系。例如 Google就可以通過直接讀取GZIP文件來比普通手工抓取更快地檢索網(wǎng)頁。

GZIP壓縮傳輸?shù)脑砣缦聢D:

按照上圖拆解出的步驟如下:

  • 客戶端向服務器請求頭中帶有:Accept-Encoding:gzip,deflate 字段,向服務器表示,客戶端支持的壓縮格式(gzip或者deflate),如果不發(fā)送該消息頭,服務器是不會壓縮的。
  • 服務端在收到請求之后,如果發(fā)現(xiàn)請求頭中含有 Accept-Encoding 字段,并且支持該類型的壓縮,就對響應報文壓縮之后返回給客戶端,并且攜帶 Content-Encoding:gzip 消息頭,表示響應報文是根據(jù)該格式壓縮過的。
  • 客戶端接收到響應之后,先判斷是否有 Content-Encoding 消息頭,如果有,按該格式解壓報文。否則按正常報文處理。

7.2、openFeign開啟GZIP壓縮:

????????openFeign支持請求/響應開啟GZIP壓縮,整體的流程如下圖:

????????上圖中涉及到GZIP傳輸?shù)闹挥袃蓧K,分別是 Application client -> Application Service、 Application Service->Application client。

????????注意:openFeign支持的GZIP僅僅是在openFeign接口的請求和響應,即openFeign消費者調(diào)用服務提供者的接口。

????????openFeign開啟GZIP步驟也是很簡單,只需要在配置文件中開啟如下配置:

feign:## 開啟壓縮compression:request:enabled: true## 開啟壓縮的閾值,單位字節(jié),默認2048,即是2k,這里為了演示效果設置成10字節(jié)min-request-size: 10mime-types: text/xml,application/xml,application/jsonresponse:enabled: true

上述配置完成之后,發(fā)出請求,可以清楚看到請求頭中已經(jīng)攜帶了GZIP壓縮,如下圖:

四、OpenFeign 的原理:

文章該部分轉(zhuǎn)自:https://blog.csdn.net/manzhizhen/article/details/110013311

? ? ? ? Feign 只是對 HTTP 調(diào)用組件進行了易用性封裝,底層還是使用我們常見的 OkHttp、HttpClient 等組件,你瞧:

????????Feign 的目標之一就讓這些 HTTP 客戶端更好用,使用方式更統(tǒng)一,更像RPC。要想了解 Spring Cloud OpenFeign 整體實現(xiàn)原理,我們需要回答如下四個問題:

  • (1)@FeignClient 如何根據(jù)接口生成實現(xiàn)(代理)類的?
  • (2)生成的實現(xiàn)(代理)類是如何適配各種HTTP組件的?
  • (3)生成的實現(xiàn)(代理)類如何實現(xiàn)HTTP請求應答序列化和反序列化的?
  • (4)生成的實現(xiàn)(代理)類是如何注入到Spring容器中的?

接下來,我們通過解讀源碼方式,逐一解答上述問題。

1、@FeignClient 如何根據(jù)接口生成實現(xiàn)類的?

? ? ? ? Fegin 使用的是 JDK 動態(tài)代理技術來生成實現(xiàn)類的,因此 Feign 的使用必須要有接口。但還有一個小問題,我們回看上面提到的 OpenFeignService?接口,里面有多個方法,每個方法有 @RequestMapping ,意味著這些方法可以映射到不同的遠端HTTP路徑,所以給整個?OpenFeignService?接口做代理時,代理類的方法必須知道對應到哪個遠端HTTP路徑,雖然我們可以在 java.lang.reflect.InvocationHandler#invoke 的方法入?yún)?Method 中去解析 @RequestMapping 拿url,但需要注意的是,大多數(shù)開源框架很忌諱在運行時高頻使用JDK的反射,因為這樣非常影響執(zhí)行效率,Dubbo 的 Provider 端也不是用反射來調(diào)用本地方法的,所以在 Feign 使用 JDK動態(tài)代理技術時,需要提前將接口(例如 OpenFeignService)帶 @RequestMapping 方法解析出來。為了探究這塊的具體實現(xiàn),我們移步原生 Feign 的 feign-core 包的核心類 ReflectiveFeign:

package feign;import feign.InvocationHandlerFactory.MethodHandler;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.LinkedHashMap; import java.util.Map;import static feign.Util.checkNotNull;public class ReflectiveFeign extends Feign {private final InvocationHandlerFactory factory;/*** creates an api binding to the {@code target}. As this invokes reflection, care should be taken* to cache the result.* 注意:這里我們隱藏了大部分非核心的代碼*/@Overridepublic <T> T newInstance(Target<T> target) {// 將@FeignClient的接口類所有帶@RequestMapping方法解析出來,map的key為方法簽名,MethodHander為包裝過的方法調(diào)用HanderMap<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();// 根據(jù)nameToHandler來組裝methodToHandlerfor (Method method : target.type().getMethods()) {methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));}// 這里通過一個InvocationHandler工廠來參見JDK動態(tài)代理中的InvocationHandler(既下面的FeignInvocationHandler)InvocationHandler handler = factory.create(target, methodToHandler);// 創(chuàng)建JDK動態(tài)代理生成代理類,這個類在Spring Cloud OpenFeign中會被注冊到Spring容器中T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),new Class<?>[]{target.type()}, handler);return proxy;}/*** Feign專用FeignInvocationHandler*/static class FeignInvocationHandler implements InvocationHandler {private final Target target;// 這里保持的是我們在newInstance解析出來的@RequestMapping(在原生Feign中是@RequestLine)方法和方法處理器的映射關系private final Map<Method, MethodHandler> dispatch;FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {this.target = checkNotNull(target, "target");this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 常規(guī)的用于AOP的動態(tài)代理會選擇調(diào)用target的method方法,但我們這里由于沒有自定義的接口實現(xiàn)類,所以直接調(diào)用我們包裝過的對應MethodHandlerreturn dispatch.get(method).invoke(args);}} }

這里順便補充下?MethodHandler 接口的定義:

package feign;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map;/*** Controls reflective method dispatch.*/ public interface InvocationHandlerFactory {InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch);/*** Like {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])}, except for a* single method.*/interface MethodHandler {Object invoke(Object[] argv) throws Throwable;}static final class Default implements InvocationHandlerFactory {@Overridepublic InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);}} }

????????看 ReflectiveFeign 的類名我們就知道它和反射有關,ReflectiveFeign 借助于JDK動態(tài)代理,根據(jù)我們的業(yè)務接口生成對應的代理類,這個代理類會根據(jù)調(diào)用的方法來直接找到已經(jīng)提前準備好的對應的 MethodHandler,直接調(diào)用即可完成Feign的使命,根據(jù)上面的使用方法,我們不難猜到 MethodHandler 里面有HTTP調(diào)用的相關信息(這些信息之前是在接口方法定義的 @RequestMapping 或 @RequestLine 之中),而且 MethodHandler#invoke 會完成真正的HTTP調(diào)用并將結果反序列化成原接口方法的返回值對象。

2、生成的實現(xiàn)(代理)類是如何適配各種HTTP組件的?

????????這個問題應該由 Feign 來回答,而不是 Spring Cloud OpenFeign,Feign 的 feign-core 模塊中有一個 Client 接口,專門用來給各個HTTP組件提供接入接口,我們看其定義:

package feign;import feign.Request.Options;import java.io.IOException;/*** Submits HTTP {@link Request requests}. Implementations are expected to be thread-safe.* 注意,為了展現(xiàn)方便,我們裁剪了部分代碼*/ public interface Client {/*** Executes a request against its {@link Request#url() url} and returns a response.** @param request safe to replay.* @param options options to apply to this request.* @return connected response, {@link Response.Body} is absent or unread.* @throws IOException on a network error connecting to {@link Request#url()}.*/Response execute(Request request, Options options) throws IOException; }

????????各個 HTTP客戶端組件的適配模塊(例如feign-okhttp、feign-httpclient等)只需要實現(xiàn)該接口就可以和 Feign 打通,而在原生的 Feign 中,選擇何種HTTP組件是自己選擇的,比如我們想使用OkHttpClient,在Consumer端可以這樣:

public class Example {public static void main(String[] args) {String response = Feign.builder().client(new OkHttpClient()).target(ProviderDemoService.class, "https://xxxx");} }

????????Spring Cloud 遵循?Spring Boot 的“約定優(yōu)于配置”的原則,通過條件注解,實現(xiàn)了通過當前項目的依賴包決定使用哪個 HTTP 組件,詳見 Spring Cloud OpenFeign 中的 org.springframework.cloud.openfeign.FeignAutoConfiguration:

@Configuration(proxyBeanMethods = false) @ConditionalOnClass(Feign.class) @EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class}) @Import(DefaultGzipDecoderConfiguration.class) public class FeignAutoConfiguration {@Configuration(proxyBeanMethods = false)@ConditionalOnClass(ApacheHttpClient.class)@ConditionalOnMissingBean(CloseableHttpClient.class)@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)protected static class HttpClientFeignConfiguration {private final Timer connectionManagerTimer = new Timer("FeignApacheHttpClientConfiguration.connectionManagerTimer", true);@Autowired(required = false)private RegistryBuilder registryBuilder;private CloseableHttpClient httpClient;@Bean@ConditionalOnMissingBean(HttpClientConnectionManager.class)public HttpClientConnectionManager connectionManager(ApacheHttpClientConnectionManagerFactory connectionManagerFactory,FeignHttpClientProperties httpClientProperties) {// 略}@Beanpublic CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,HttpClientConnectionManager httpClientConnectionManager,FeignHttpClientProperties httpClientProperties) {// 略}@Bean@ConditionalOnMissingBean(Client.class)public Client feignClient(HttpClient httpClient) {return new ApacheHttpClient(httpClient);}}@Configuration(proxyBeanMethods = false)@ConditionalOnClass(OkHttpClient.class)@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)@ConditionalOnProperty("feign.okhttp.enabled")protected static class OkHttpFeignConfiguration {private okhttp3.OkHttpClient okHttpClient;@Bean@ConditionalOnMissingBean(ConnectionPool.class)public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,OkHttpClientConnectionPoolFactory connectionPoolFactory) {Integer maxTotalConnections = httpClientProperties.getMaxConnections();Long timeToLive = httpClientProperties.getTimeToLive();TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);}@Beanpublic okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, ConnectionPool connectionPool,FeignHttpClientProperties httpClientProperties) {// 略}@Bean@ConditionalOnMissingBean(Client.class)public Client feignClient(okhttp3.OkHttpClient client) {return new OkHttpClient(client);}} }

????????從上面各種復雜的條件注解來看,如果我們項目中引入了 feign-httpclient 包(即ApacheHttpClient),并且配置了“feign.httpclient.enable”的值為 true 時,那么就會使用HttpClient,其他的HTTP組件也是類似的方式來判斷和加載。

3、生成的實現(xiàn)(代理)類如何實現(xiàn)HTTP請求應答序列化和反序列化的?

原生的Feign允許你添加額外的解碼器,官方給出了Consumer的例子:

public class Example {public static void main(String[] args) {// 這里假定ProviderDemoService中有一個返回MyResponse的方法MyResponse response = Feign.builder().decoder(new GsonDecoder()).client(new OkHttpClient()).target(ProviderDemoService.class, "https://xxxx");} }

為了能做到這一點,原生Feign提供了?Decoder?和?Encoder?兩個接口(本文我們只重點關注解碼部分):

public interface Decoder {/*** Decodes an http response into an object corresponding to its* {@link java.lang.reflect.Method#getGenericReturnType() generic return type}. If you need to* wrap exceptions, please do so via {@link DecodeException}.** @param response the response to decode* @param type {@link java.lang.reflect.Method#getGenericReturnType() generic return type} of the* method corresponding to this {@code response}.* @return instance of {@code type}* @throws IOException will be propagated safely to the caller.* @throws DecodeException when decoding failed due to a checked exception besides IOException.* @throws FeignException when decoding succeeds, but conveys the operation failed.*/Object decode(Response response, Type type) throws IOException, DecodeException, FeignException; }public interface Encoder {/*** Converts objects to an appropriate representation in the template.** @param object what to encode as the request body.* @param bodyType the type the object should be encoded as. {@link #MAP_STRING_WILDCARD}* indicates form encoding.* @param template the request template to populate.* @throws EncodeException when encoding failed due to a checked exception.*/void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException; }

????????換成 Spring Cloud OpenFeign 的話,就得和Spring的Web體系打通了,這里就不得不提一個構造類即?FeignClientsConfiguration:

// 注意:為了演示方便,對其進行了代碼裁剪 @Configuration(proxyBeanMethods = false) public class FeignClientsConfiguration {@Autowired// 這里將Spring Web的消息轉(zhuǎn)換器機制注入進來private ObjectFactory<HttpMessageConverters> messageConverters;@Bean@ConditionalOnMissingBean// 構造解碼Decoder的Spring Beanpublic Decoder feignDecoder() {// 這里的SpringDecoder實現(xiàn)了Feign的Decoder接口,并且將Spring Web的消息轉(zhuǎn)換器設置到SpringDecoder來使用return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)));}@Bean@ConditionalOnMissingBean// 構造編碼Encoder的Spring Beanpublic Encoder feignEncoder(ObjectProvider<AbstractFormWriter> formWriterProvider) {return springEncoder(formWriterProvider);}private Encoder springEncoder(ObjectProvider<AbstractFormWriter> formWriterProvider) {AbstractFormWriter formWriter = formWriterProvider.getIfAvailable();if (formWriter != null) {return new SpringEncoder(new SpringPojoFormEncoder(formWriter), this.messageConverters);}else {return new SpringEncoder(new SpringFormEncoder(), this.messageConverters);}} }

那我們看看?SpringDecoder?拿到Spring Web的解碼器后如何使用:

// 注意:裁剪了部分代碼 public class SpringDecoder implements Decoder {private ObjectFactory<HttpMessageConverters> messageConverters;public SpringDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {this.messageConverters = messageConverters;}@Overridepublic Object decode(final Response response, Type type) throws IOException, FeignException {if (type instanceof Class || type instanceof ParameterizedType || type instanceof WildcardType) {HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(type,this.messageConverters.getObject().getConverters());// 直接使用了。。。return extractor.extractData(new FeignResponseAdapter(response));}throw new DecodeException(response.status(), "type is not an instance of Class or ParameterizedType: " + type,response.request());} }

到此為止,相信你對編解碼這塊已經(jīng)有一定的了解。

4、生成的實現(xiàn)(代理)類是如何注入到Spring容器中的?

????????Spring Cloud OpenFeign 如何將動態(tài)生成的代理類和Spring容器打通?還記得我們前面說的 @EnableFeignClients 嗎?這時需要我們在使用 Spring Cloud OpenFeign 時顯式的在一個能被 Spring 容器掃到并加載的類上使用的,@EnableFeignClients 的定義如下:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(FeignClientsRegistrar.class) public @interface EnableFeignClients {// 注解內(nèi)容省略 }

????????就是這里的 @Import 提前加載 Spring Bean 的方式,觸發(fā)了 FeignClientRegistrar 的初始化,而 FeignClientRegistrar 由于實現(xiàn)了 ImportBeanDefinitionRegistrar 接口,我們知道在處理 @Configuration 類時可以通過 Import 注冊其他 Spring Bean 定義的能力,而前面說過,我們還不知道哪些接口使用了 @FeignClient,所以在 FeignClientRegistrar 中我們需要做的就是掃描某些路徑(該路徑由配置Spring掃描路徑包括@EnableFeignClients中配置的路徑)的接口類,識別對應的 @FeignClient ,給這些接口類創(chuàng)建代理對象。而為了把這些代理對象注入到Spring 容器中,所以還得借助 FactoryBean 的能力。我們先看下 ImportBeanDefinitionRegistrar 的實現(xiàn):

// 注意:裁剪了大量代碼 class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {private ResourceLoader resourceLoader;private Environment environment;@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {this.resourceLoader = resourceLoader;}@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {// 獲取 @EnableFeignClients 上的相關屬性并用這些屬性做一些基本配置Bean的注冊registerDefaultConfiguration(metadata, registry);// 注冊BeanregisterFeignClients(metadata, registry);}private void registerDefaultConfiguration(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {// 略}public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {LinkedHashSet<BeanDefinition> candidateComponents = new LinkedHashSet<>();Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());final Class<?>[] clients = attrs == null ? null : (Class<?>[]) attrs.get("clients");if (clients == null || clients.length == 0) {// 獲取包路徑下的掃描器ClassPathScanningCandidateComponentProvider scanner = getScanner();scanner.setResourceLoader(this.resourceLoader);scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));Set<String> basePackages = getBasePackages(metadata);for (String basePackage : basePackages) {// 將所有 @FeignClient 的接口的BeanDefinition拿到candidateComponents.addAll(scanner.findCandidateComponents(basePackage));}} else {for (Class<?> clazz : clients) {candidateComponents.add(new AnnotatedGenericBeanDefinition(clazz));}}for (BeanDefinition candidateComponent : candidateComponents) {if (candidateComponent instanceof AnnotatedBeanDefinition) {AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();// 對,這里要求必須是接口Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());// 根據(jù)這些屬性和接口來注冊FeignClient BeanregisterFeignClient(registry, annotationMetadata, attributes);}}}private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,Map<String, Object> attributes) {String className = annotationMetadata.getClassName();// 使用FactoryBean,將Bean的具體生成過程收攏到FeignClientFactoryBean之中BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);definition.addPropertyValue("type", className);definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias});// 將這個使用了 @FeignClient 的接口的工廠Bean的 BeanDefinition 注冊到Spring容器中BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);} }

????????可以看出,關鍵邏輯又回到 FeignClientFactoryBean 拿到業(yè)務接口、@EnableFeignClient 和 @FeignClient 的數(shù)據(jù)后如何去構造代理類了,而 FeignClientFactoryBean 內(nèi)部其實使用的是原生 Feign 的 API 來構建代理對象。

參考文章:openFeign奪命連環(huán)9問,這誰受得了?

總結

以上是生活随笔為你收集整理的SpringCloud OpenFeign 远程HTTP服务调用用法与原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

91成人亚洲| 麻豆你懂的 | 99视频免费 | 成人av免费播放 | 欧美最新另类人妖 | 国产福利小视频在线 | 日日干天天爽 | 日韩久久一区二区 | 亚洲欧美视频在线观看 | 99欧美精品 | 国产成人精品免高潮在线观看 | 一区二区三区四区五区在线视频 | 国产亚洲精品电影 | 日韩精品一区在线观看 | 最新中文字幕视频 | 日本狠狠色 | 日韩一级黄色片 | av成人免费在线观看 | 综合国产在线观看 | 久草www | 一级免费看 | 欧美精品第一 | 国产一区自拍视频 | 亚洲欧美日韩国产一区二区 | 92精品国产成人观看免费 | 99热精品在线观看 | japanese黑人亚洲人4k | 国产一二区视频 | 成人午夜在线电影 | 国产精品久久久久影视 | 91在线视频| 欧美日本一区 | 一区二区三区免费在线观看视频 | 国产成人精品一区二区三区网站观看 | 九九精品视频在线观看 | av电影中文 | 色播99| 麻豆 91 在线| 久视频在线播放 | 国产精品久久久久三级 | 九九精品视频在线看 | 狂野欧美激情性xxxx欧美 | 亚洲精品影视在线观看 | 亚洲激情av | av资源免费在线观看 | 欧美日韩精品网站 | 日韩中文字幕免费电影 | 99人成在线观看视频 | 涩涩网站在线看 | 天天干天天在线 | 日韩精品一区二区在线 | 久久婷综合| 丰满少妇一级片 | 视频一区久久 | 亚洲免费婷婷 | 久久久福利视频 | 97福利| 久草在线最新免费 | 免费网站在线观看成人 | 在线观看视频中文字幕 | 亚洲伦理电影在线 | 99热在| 久久99久久99免费视频 | 成人精品视频 | 欧美日韩精品免费观看 | 欧美国产日韩中文 | 国产免费视频一区二区裸体 | 黄色资源在线 | 国产成人免费在线 | 久久99这里只有精品 | 日韩国产精品久久 | 伊人婷婷久久 | 人人射人人爽 | 亚洲欧美日韩精品久久奇米一区 | 国产1区2 | 国产中文字幕网 | 国产精品a成v人在线播放 | 国产精品成人品 | 岛国一区在线 | 亚洲视频免费在线 | 中文在线免费视频 | 中文字幕久久久精品 | 麻豆久久 | 一区二区三区免费在线观看视频 | 国产成人三级在线播放 | 永久免费的av电影 | 免费三级网 | 久久五月情影视 | av成人免费在线观看 | 午夜久久久久 | 国产又黄又硬又爽 | 色综合久 | av久久久久久| 婷婷在线视频 | 日韩免费播放 | 五月激情天 | 在线观看精品一区 | 在线播放 一区 | 正在播放一区 | www.五月天激情 | 中文字幕av网站 | 国产精品久久99精品毛片三a | 国产视频一区在线免费观看 | 夜又临在线观看 | 亚洲九九九在线观看 | 国产精品福利小视频 | 91在线视频免费91 | 久久av一区二区三区亚洲 | 久久国产精品区 | 国产精品21区 | 97色婷婷人人爽人人 | 超碰在线97观看 | 亚洲成人高清在线 | 91精品天码美女少妇 | 亚洲第一av在线 | 黄网在线免费观看 | 丁香午夜婷婷 | 国产精品理论片在线观看 | 日韩网站免费观看 | 91手机在线看片 | 91亚洲网站| 日韩性色 | 日韩网站视频 | 91你懂的 | 久久艹欧美 | 免费av一级电影 | 欧女人精69xxxxxx| 日日天天狠狠 | 91香蕉国产在线观看软件 | 91免费高清 | 久久久国产影视 | 亚洲狠狠操 | 日韩h在线观看 | av不卡免费在线观看 | 亚洲国产精品99久久久久久久久 | 欧美日韩国产二区 | 午夜精品视频一区 | 992tv人人网tv亚洲精品 | 成人免费在线观看电影 | 亚洲精品国精品久久99热 | 97人人添人澡人人爽超碰动图 | 日韩免费在线视频观看 | 免费看久久 | 亚洲精品视频网站在线观看 | 黄色小说18 | 国产精品三级视频 | 免费观看日韩 | 婷婷国产精品 | 国产一区二区三区四区大秀 | av网站免费线看精品 | 新版资源中文在线观看 | 一区二区三区视频在线 | 国产精品国产亚洲精品看不卡 | 婷婷激情在线 | 国产v在线 | 欧美在线观看视频一区二区三区 | 亚洲桃花综合 | 午夜av激情| 91福利区一区二区三区 | 日韩电影在线观看一区 | 亚洲综合视频在线 | 欧美精品国产精品 | 久久九九久久精品 | 成人av一区二区在线观看 | 九九久久国产 | 夜夜躁日日躁狠狠躁 | 日韩3区 | 夜夜摸夜夜爽 | 91豆花在线观看 | 久久久国产网站 | www视频在线免费观看 | 国产高清福利在线 | 欧美精品三级 | 狠狠色狠狠色终合网 | 丁香花中文字幕 | 精品视频免费 | www.人人草| 国产免费中文字幕 | 一级片色播影院 | 免费成人黄色 | 天天操天天曰 | 欧美一区日韩精品 | 色香蕉在线视频 | 国产色婷婷精品综合在线手机播放 | 黄色在线观看www | av先锋影音少妇 | 免费黄色小网站 | 中文字幕免费观看 | 天堂网一区 | 成人在线一区二区三区 | 91国内在线视频 | 久久国产精品色av免费看 | 99久久激情 | 99久久精品国产网站 | 久久久久免费精品视频 | 91探花国产综合在线精品 | 91亚洲狠狠婷婷综合久久久 | 日本护士三级少妇三级999 | 欧美a级在线播放 | 4438全国亚洲精品观看视频 | 国产精品爽爽爽 | 欧美a级在线免费观看 | 日日操日日插 | 高清日韩一区二区 | 国产精品网址在线观看 | 久久网站免费 | 久久久国产99久久国产一 | 九九热只有这里有精品 | 欧美一区二区在线 | 中文字幕在线视频网站 | 亚洲专区 国产精品 | 欧美视频在线观看免费网址 | 国产亚洲精品v | 99这里只有久久精品视频 | 亚洲精品免费在线 | 日韩黄色免费在线观看 | 91观看视频| 国产精品理论视频 | 四虎成人精品永久免费av | 久久成人毛片 | 美女黄频在线观看 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 99热精品国产| 中文字幕一区二 | 欧美乱码精品一区 | 欧美精彩视频 | 狠狠综合网 | 色综合亚洲精品激情狠狠 | 欧美日韩免费看 | 亚洲成人高清在线 | 三级黄色片子 | 成年人免费av | 久久av免费 | av一级片网站 | 日韩av一区二区三区在线观看 | 日韩1页| 波多野结衣电影一区二区三区 | 欧美在线一级片 | 一区二区三区精品在线 | 五月天激情开心 | 最近中文字幕在线 | 午夜精品剧场 | 特级西西444www大胆高清无视频 | 99综合电影在线视频 | 在线播放日韩 | 999日韩 | 亚洲精品综合一二三区在线观看 | 18性欧美xxxⅹ性满足 | 久久躁日日躁aaaaxxxx | 九色91在线视频 | 亚洲精品在线观看免费 | 98涩涩国产露脸精品国产网 | 国产一性一爱一乱一交 | 91视频免费看 | 亚洲高清视频在线观看免费 | 91成品人影院 | 嫩草av影院 | 91麻豆精品国产自产 | 97av视频在线 | 国产精品久久久久久一二三四五 | 99视频99 | 欧美亚洲一级片 | 在线视频久 | 日韩在线激情 | 黄污视频大全 | 亚洲电影图片小说 | 五月天色网站 | 久久激情片 | 久久一区精品 | 亚洲乱码精品久久久久 | 精品嫩模福利一区二区蜜臀 | 久久精品99国产精品亚洲最刺激 | 日韩三级视频 | 欧美午夜一区二区福利视频 | 天天操天天拍 | 色婷婷色 | 午夜丰满寂寞少妇精品 | 国产成人久久 | 毛片基地黄久久久久久天堂 | 丝袜美腿av| 久久视频二区 | 99精品国产福利在线观看免费 | 久久精品国产免费 | 麻豆视频91 | 久草网视频 | 99免费看片| 深爱开心激情网 | 亚洲视频中文 | 一区二区 不卡 | 天天综合网久久 | 99精品免费视频 | 色婷婷免费视频 | 亚洲在线| 九九视频在线观看视频6 | av高清网站在线观看 | 国产123区在线观看 国产精品麻豆91 | 久久午夜免费观看 | 91黄色在线视频 | 成人黄色大片在线免费观看 | 1024手机基地在线观看 | 麻豆一区在线观看 | 久久999久久 | 色视频在线免费观看 | 激情视频一区二区三区 | 国产精品麻豆99久久久久久 | 久久成年人视频 | 日韩欧美aaa | 久久久国产成人 | 国产不卡免费视频 | 国产亚洲精品bv在线观看 | 伊人首页 | 成人精品一区二区三区电影免费 | 亚洲最新在线视频 | 狠狠夜夜| 中文字幕亚洲不卡 | 男女激情免费网站 | 国产精品视频在线观看 | www.成人久久| www毛片com| 久久五月婷婷丁香社区 | 四虎www com| 天天操天天干天天干 | 久久高清精品 | 亚洲成人午夜在线 | 免费av一级电影 | 精品久久网 | 成人免费在线播放视频 | av成人在线看 | 伊人黄色网 | 三级黄色片在线观看 | 久久国精品 | 久久理论视频 | 在线观看一 | 亚洲黄色在线 | 午夜性福利 | 日韩在线观看一区二区 | 欧美网址在线观看 | 国产成人精品亚洲精品 | 色五丁香| 免费h在线观看 | 久久综合久久伊人 | 97在线观看免费高清完整版在线观看 | 黄色在线看网站 | 99视频精品视频高清免费 | 999毛片| 国产精品99爱 | 免费在线观看污 | 麻豆精品在线 | 欧美老人xxxx18 | 国产精品一区二区麻豆 | 久久久精品在线观看 | av品善网| 国产色女 | 精品高清视频 | 中文字幕二区在线观看 | 在线最新av | 黄色午夜网站 | 成人91在线 | 国精产品999国精产品岳 | 久久激情视频免费观看 | 亚洲国产偷 | 久久噜噜少妇网站 | 久久大视频| 在线观看一级视频 | 久久久久久久福利 | 99色在线视频 | 96精品高清视频在线观看软件特色 | 91精品国产入口 | 国产精品视频全国免费观看 | av中文天堂在线 | av高清免费| 高清美女视频 | 亚洲电影自拍 | 水蜜桃亚洲一二三四在线 | 91香蕉视频在线下载 | 色久五月| 国产精彩视频 | 日韩精品一区二区三区高清免费 | 在线观看视频福利 | 综合网在线视频 | 91中文字幕一区 | 久久久香蕉视频 | 久精品视频在线观看 | 国产一区二区三区免费在线 | 777视频在线观看 | 91在线日本 | 97视频总站 | 久久人人干 | 日韩欧美一区二区在线播放 | 亚洲高清视频在线播放 | 日韩精品一区二区三区不卡 | www.99在线观看 | 免费看国产视频 | 在线视频免费观看 | 精品国产自在精品国产精野外直播 | 久久综合九色综合欧美就去吻 | 精品99免费 | 一区二区 不卡 | 婷婷九月丁香 | 亚洲精品黄色在线观看 | 中文字幕av一区二区三区四区 | 国产青春久久久国产毛片 | 中文字幕乱码电影 | 伊人天天综合 | 国产一区免费视频 | 免费在线播放av电影 | 欧美资源在线观看 | 精油按摩av | 免费在线观看av电影 | 91精品日韩 | 国产精品欧美一区二区 | 国产私拍在线 | 久久久av免费 | 美女久久视频 | 一区二区久久 | 国产精品久久久久久超碰 | 黄色av一级 | 国产精品久久久久久久久久久久午夜片 | 狠日日| 国产精品99在线播放 | 91精品国产99久久久久久红楼 | 国产精品美女久久久免费 | 色福利网 | 69国产在线观看 | 午夜国产成人 | 国产伦理久久精品久久久久_ | 久久久影片 | 国产精品免费大片视频 | 欧美三级免费 | 国产一区二区精品久久91 | 色视频在线观看 | 日韩高清不卡一区二区三区 | 五月开心婷婷 | 一区二区中文字幕在线 | 99久在线精品99re8热视频 | 超碰人人干人人 | 亚洲国产精品日韩 | 能在线观看的日韩av | 天天婷婷| 九九热99视频 | 色网免费观看 | 色婷婷国产在线 | 欧美日韩久久不卡 | 天天在线视频色 | 国产一区二区手机在线观看 | 欧美日本啪啪无遮挡网站 | 色婷婷视频网 | 日本久久精 | 97视频人人免费看 | 激情图片qvod | 狠狠操狠狠干天天操 | 亚洲免费国产视频 | 97精品国产97久久久久久免费 | 91成人免费看片 | 亚洲狠狠婷婷综合久久久 | 久久99精品视频 | 久久人人爽人人爽人人 | 国产一区高清在线 | 久草视频免费在线观看 | 亚洲午夜av | 久久理论影院 | 亚洲天堂va | 日韩一区二区三免费高清在线观看 | 丁香婷婷综合色啪 | 天天射射天天 | 国产一级视频在线免费观看 | 成人黄色电影视频 | 亚洲精品国产日韩 | 美女网站黄在线观看 | 九九九免费视频 | 国产不卡免费 | 国产免费xvideos视频入口 | 美国av大片| 久久成电影 | 亚洲精品天天 | 中文字幕精品三级久久久 | 美女久久视频 | 青青草国产精品 | 亚洲精品一区中文字幕乱码 | 中国一级特黄毛片大片久久 | 亚洲精品视频免费在线观看 | 三级在线国产 | 91免费高清在线观看 | 黄色av电影在线 | 欧美成人h版电影 | 婷婷久久亚洲 | 最新日韩中文字幕 | 99久热在线精品 | 国产小视频在线免费观看 | 一本一道久久a久久精品 | 国产在线精品国自产拍影院 | 国产字幕在线播放 | 精品国产99 | 国产在线1区 | 亚洲精品视频在线播放 | 日韩精品一区二区在线观看 | 综合婷婷久久 | 日韩欧美高清视频在线观看 | 日韩免费电影网 | 久保带人| 91九色视频 | 欧美色图另类 | 欧美精品乱码久久久久 | 中文字幕91在线 | 国产裸体视频bbbbb | 正在播放五月婷婷狠狠干 | 免费99视频 | 国产视频一区二区在线播放 | 香蕉久草在线 | 黄色一及电影 | 久久久91精品国产 | 久久免费a| 中文视频在线播放 | 国产精品白浆视频 | 日韩免费一级a毛片在线播放一级 | 免费色婷婷| 奇米影视999| 国产三级久久久 | 色视频网址 | 日韩av一区二区在线播放 | 成人超碰97 | 天天操夜夜曰 | 成人av影视观看 | 久久精品看 | 欧美精品第一 | 亚洲综合色视频 | 国产精品久久网 | 日本中文字幕网站 | 一本色道久久综合亚洲二区三区 | 亚洲精品国精品久久99热 | 国产aaa大片 | 一区三区在线欧 | 亚洲免费观看视频 | 国产亚洲精品综合一区91 | 日韩av一区二区三区 | 久久久久国产精品视频 | 能在线看的av | 欧美一级xxxx| 在线探花 | 超碰人人在线 | 日韩精品免费一区二区三区 | 毛片精品免费在线观看 | 免费看污在线观看 | 久久精品国产一区 | 精品国产91亚洲一区二区三区www | 91大神电影 | 成人影音av | 日日躁你夜夜躁你av蜜 | 日本午夜免费福利视频 | 在线国产精品视频 | 亚洲成人在线免费 | 国产色在线视频 | 91成人精品视频 | 日韩av偷拍 | 国产免费又粗又猛又爽 | 亚洲国产高清在线观看视频 | a黄色片在线观看 | 国产精品一区二区无线 | 在线免费观看国产 | 欧美a在线免费观看 | 91久久精品一区二区二区 | 黄色亚洲片| 国产成人精品久久久 | 亚州性色| 福利一区二区三区四区 | 国产视频首页 | 免费日韩 精品中文字幕视频在线 | 91精品视频一区 | 久久草av| 国产精品系列在线观看 | 91视频高清 | 欧美精品一区二区在线观看 | 成人精品国产免费网站 | 色婷婷97| 国产精品久久久久久久久久免费 | 精品女同一区二区三区在线观看 | 国产九九热 | 亚洲成人欧美 | 免费成人av在线看 | 日韩三级视频在线观看 | 成人不用播放器 | 久久综合免费 | 久久久穴 | 欧美精品久久99 | 日韩有码在线播放 | 最新日韩在线观看视频 | 欧美日韩网址 | 四虎成人免费观看 | 国产一级小视频 | 亚洲欧美综合精品久久成人 | 91亚色视频在线观看 | 色综合天天做天天爱 | 91夫妻自拍 | 欧美成人h版 | 91精品国产一区 | 一级黄色av | 91传媒免费观看 | 六月丁香婷婷久久 | 精品视频久久久 | 国产黄影院色大全免费 | 丁香久久五月 | 色婷婷综合视频在线观看 | 欧美99精品| 久久影院中文字幕 | 麻豆91精品 | 免费亚洲片 | 91传媒视频在线观看 | 日日夜夜狠狠干 | 久久九九影视网 | 人人插人人爱 | 久久免费高清 | 亚洲国产高清视频 | 亚洲国产精久久久久久久 | 国产原创av在线 | 成人av资源网 | 亚洲精欧美一区二区精品 | 亚洲激色 | 国产男女爽爽爽免费视频 | 中文字幕在线观看第一页 | 日本公妇在线观看 | 国产麻豆剧果冻传媒视频播放量 | 日日操网 | 91中文在线 | www.天天草| 天天艹天天| 免费看的黄网站软件 | av不卡在线看 | 成人综合婷婷国产精品久久免费 | 69性欧美| av国产网站 | 国产高清久久久久 | 色偷偷网站视频 | 国产永久免费 | 亚洲精品电影在线 | 精品视频久久 | 欧美精品久久久久久久久久丰满 | 黄色网www | 韩国av免费看 | 91久久偷偷做嫩草影院 | 日本性生活免费看 | zzijzzij日本成熟少妇 | 亚洲精品高清视频在线观看 | 日韩xxxxxxxxx | 精品国产欧美 | 国产精品ssss在线亚洲 | 国产高清视频在线播放 | 久草在线费播放视频 | 色www.| 欧美日韩国产二区三区 | 国产一线天在线观看 | 手机在线小视频 | 国产精品久久久久aaaa九色 | 伊人官网 | 免费看av片网站 | 国内精品久久久久久久97牛牛 | 国产在线一区观看 | 日韩国产欧美在线播放 | 国产一级黄色av | 国产护士在线 | 免费99精品国产自在在线 | 日韩69av | 99精品欧美一区二区三区 | 草久热 | www日韩在线观看 | 日韩免费一级电影 | 色婷婷激婷婷情综天天 | 国产一级不卡视频 | 欧美视频二区 | 91av久久| 欧美久久久一区二区三区 | 免费精品视频在线 | 久久精品伊人 | 日韩av电影一区 | 国产精品永久在线 | 成人影片在线播放 | 一区二区中文字幕在线 | 欧美日韩一二三四区 | 精品一区二区久久久久久久网站 | 精品国产一区二区久久 | 亚洲开心色| 99热这里只有精品1 av中文字幕日韩 | 伊人亚洲综合网 | 欧美在一区 | 中文字幕国产视频 | 国产一级片在线播放 | 国产亚洲欧美日韩高清 | 亚洲综合导航 | 九九综合在线 | 在线视频 影院 | 97色资源| 国产黄在线免费观看 | 天天色图 | 亚洲成av人片在线观看www | 黄网站免费久久 | 人人干人人草 | 日日成人网 | 在线观看激情av | a级片久久 | 国产xxxx做受性欧美88 | 日韩精品一区二区在线视频 | 欧美一区二区三区四区夜夜大片 | 亚洲精品影视 | 日韩黄色一级电影 | 婷婷激情五月 | 成年人国产视频 | 中文字幕一区二区三 | 国产精品12 | 色窝资源| 中文字幕国产精品一区二区 | 999ZYZ玖玖资源站永久 | 久久综合久久鬼 | 国产精品视频免费看 | 日日操日日操 | 国产精品少妇 | 精品国产区在线 | 久久久69| 97精品国产97久久久久久久久久久久 | www.婷婷com| av手机在线播放 | 欧美日韩国产在线观看 | 青春草免费在线视频 | 激情五月婷婷 | 97色婷婷| 亚洲粉嫩av| 成人资源站 | 久久深夜 | 视频国产在线观看18 | 欧美欧美| 中文字幕在线视频国产 | 中文字幕 国产精品 | 精品成人久久 | 在线免费观看黄色av | 欧美午夜寂寞影院 | 国产精品高潮呻吟久久久久 | 国产原创在线 | 免费影视大全推荐 | 国产日产高清dvd碟片 | 国产精品久久久久久久av大片 | 日韩在线观看视频免费 | 亚洲精品视频免费在线 | 国产精品久久电影观看 | 中文字幕在线免费观看 | 最新av网址在线观看 | 国产精品综合久久久久久 | 日日干网| 欧美视频在线观看免费网址 | 黄色免费观看网址 | 四虎永久免费在线观看 | 日韩视频免费观看高清完整版在线 | 天天玩夜夜操 | 99精品一区二区 | 91九色网站 | 亚洲一二三久久 | a在线v| 欧美成人aa | 国产视频黄 | 久久久高清视频 | av福利网址导航 | 国内毛片毛片 | 中文字幕在线观看播放 | 波多野结衣视频一区 | 深爱婷婷网 | www.久久婷婷 | 欧美精品久久久 | 国产中文字幕免费 | 中文字幕韩在线第一页 | 国产亚洲精品免费 | 在线中文字母电影观看 | 福利一区二区三区四区 | 久久激情电影 | 2021国产精品视频 | 午夜精品电影一区二区在线 | 久久久久女教师免费一区 | 一二区电影 | av在线观 | 婷婷丁香av | 亚洲精品免费观看视频 | 婷婷久久综合网 | 国产亚洲精品无 | 久久高清毛片 | 视频国产 | 亚洲免费观看在线视频 | 在线观看播放av | 在线观看中文字幕一区二区 | 欧美人交a欧美精品 | 人操人 | 国产精品国产亚洲精品看不卡 | 色噜噜狠狠狠狠色综合久不 | 亚洲人成免费 | 91免费网址| 亚洲成年人在线播放 | 日韩美女免费线视频 | 999久久久久久 | 在线国产一区 | 国产综合久久 | 久久99久久99久久 | 亚洲精品小视频在线观看 | 美女久久久 | 超碰免费久久 | 免费看的黄色 | 狂野欧美激情性xxxx欧美 | 国产一级大片免费看 | 欧美日本在线视频 | 日日夜夜干 | 精品一区二区久久久久久久网站 | 91九色免费视频 | 国产成人免费在线 | 狠狠干夜夜爱 | 在线免费色 | 天天干人人干 | 成年人视频在线 | 中文字幕视频 | 婷婷色五 | 国产精品一二 | 免费观看一级特黄欧美大片 | 亚洲黄色免费在线看 | 西西44人体做爰大胆视频 | 麻豆传媒视频在线 | 欧美成人xxx | 毛片在线播放网址 | 久久午夜精品视频 | av成年人电影 | 狠狠躁日日躁狂躁夜夜躁av | 最近更新的中文字幕 | 国产一区二区三区在线 | 66av99精品福利视频在线 | 一区二区精品在线观看 | 韩国一区二区av | 视频一区亚洲 | 国产精品69久久久久 | 天堂av在线中文在线 | 最新国产精品久久精品 | 国产亚洲情侣一区二区无 | 91精品国产欧美一区二区成人 | 一区二区三区视频网站 | 91精品在线视频 | 久久久久久免费网 | 国产亚洲精品成人av久久影院 | 亚洲国产人午在线一二区 | 日韩中文字幕免费电影 | 国产尤物一区二区三区 | 精品国产成人av在线免 | 四虎最新域名 | 999视频在线播放 | 久久成人欧美 | 欧美色图一区 | 免费视频成人 | av看片在线| 国产人成看黄久久久久久久久 | 欧美日韩精 | 天天艹天天操 | 亚洲va欧美 | 国产成人在线免费观看 | 狠狠干美女 | 国产综合视频在线观看 | 国产精品久久久精品 | 国产色婷婷精品综合在线手机播放 | 97视频在线观看视频免费视频 | 丁香婷婷综合网 | 免费观看性生活大片3 | av在线网站免费观看 | 亚洲视频网站在线观看 | 97超碰人人看| 日韩中出在线 | 一区二区三区高清 | 青青河边草观看完整版高清 | 久久久精品视频成人 | 99re亚洲国产精品 | www婷婷 | 亚洲精品97 | 五月天av在线 | 成人午夜精品久久久久久久3d | 欧美激情第28页 | 99久久精品久久久久久清纯 | 狠狠干.com| 操少妇视频 | 亚洲一级片 | 狠色在线 | 欧美精品一区二区性色 | 超碰人人干人人 | 欧美日韩国产欧美 | 久二影院 | 国产区第一页 | 久久久久久国产精品久久 | 色天天综合网 | 天天插天天 | 久久精品—区二区三区 | 91精品系列 | 国产高潮久久 | 狠狠色狠狠色综合系列 | 亚洲va欧洲va国产va不卡 | 麻豆你懂的 | 国产精品九九九九九九 | 欧美另类xxxxx | wwxxx日本| 久久久亚洲国产精品麻豆综合天堂 | 色诱亚洲精品久久久久久 | 5月丁香婷婷综合 | 欧美一级久久 | 91手机视频 | 精品国产乱码久久久久久1区二区 | 国产精品 日韩 欧美 | 精品亚洲视频在线 | 国产96视频| 91在线观看欧美日韩 | 不卡电影免费在线播放一区 | 日韩精品一区二区在线观看视频 | 91成人在线免费观看 | 国产韩国日本高清视频 | 欧美性网站 | 91视频免费观看 | 国产精品理论片 | 中文字幕在线看视频国产中文版 | 国产丝袜 | 激情亚洲综合在线 | 日本精品一 | 天天操福利视频 | 深爱开心激情 | 欧美日韩超碰 | 少妇搡bbbb搡bbb搡忠贞 | 96视频免费在线观看 | 色视频网站在线观看一=区 a视频免费在线观看 | 中文字幕在线观看不卡 | 人人操日日干 | 精品久久久久久久久中文字幕 | 中国一级特黄毛片大片久久 | 三级免费黄 | 91麻豆精品国产 | 国产亚洲日| 五月天色站 | 欧美久久久久久久久久久久 | 国产午夜麻豆影院在线观看 | 麻豆视频免费在线 | 日本精品视频一区 | 国产在线一区观看 | 字幕网资源站中文字幕 | www黄色软件 | 日韩有码中文字幕在线 | 国产精品爽爽久久久久久蜜臀 | 啪啪凸凸| 久久99九九99精品 | 91传媒免费在线观看 | 99精品免费| 久久精品人 | 精品久久久久久久久久久院品网 | 国产精品 999 | 蜜臀aⅴ国产精品久久久国产 | 婷婷日| 国产高清日韩 | 欧美在线观看禁18 | 免费成人在线观看 | jizzjizzjizz亚洲 | 久久无码精品一区二区三区 | 天天操天天操一操 | 久久久www | 久草在线视频首页 | 精品久久精品 | 国产精品乱码高清在线看 | 国产精品网红福利 | 欧美日韩在线视频一区二区 | 四虎国产视频 | 青青草久草在线 | 久保带人 | www久久久 | 亚洲国产中文字幕在线视频综合 | 久久久影院一区二区三区 | 天天干.com| 成人97视频一区二区 | 在线免费三级 | 亚洲视频在线观看网站 | 免费黄色在线网址 | 看黄色91| 国产高清av在线播放 | 最新av免费在线观看 | 97视频人人免费看 | 香蕉精品视频在线观看 | 久要激情网| 国产一区二区在线视频观看 | 国产一性一爱一乱一交 | 国产人成在线视频 | 97国产大学生情侣白嫩酒店 | 九九九热精品免费视频观看网站 | 日日夜夜操操 | 一区二区三区免费在线播放 | 97色综合| 在线视频亚洲 | 精品在线你懂的 | 91欧美日韩国产 | 99re久久资源最新地址 | 久久av免费 | 亚洲国产精品99久久久久久久久 | 欧洲精品视频一区 | 日韩二区三区在线 | 欧美a免费 | 91av网站在线观看 | 91在线中文字幕 | 91亚洲在线观看 | 99热在线国产 |