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

Spring Cloud Gateway網關全局核心過濾器路由執行過程詳解

網絡 網絡管理
如果URL有一個lb(例如lb://order-service),它使用Spring Cloud ReactorLoadBalancer將名稱(在本例中為order-service)解析為一個實際的主機和端口,并替換相同屬性中的URI。?

環境:SpringBoot2.7.10 + Spring Cloud gateway3.1.6

1 RouteToRequestUrlFilter

根據路由配置的url信息,構建成為要訪問的目標地址,如下路由配置:?

spring:
cloud:
gateway:
enabled: true
# 全局超時配置
httpclient:
connect-timeout: 10000
response-timeout: 5000
discovery:
locator:
enabled: true
lowerCaseServiceId: true
# 這里是全局過濾器,也就是下面在介紹過濾器執行的時候一定會執行StripPrefixGatewayFilterFactory#apply
# 返回的過濾器,如下路由配置:該過濾器會將你的請求轉換為:http://localhost:8088/demos,保存到上下文中
# ServerWebExchange#getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI())
default-filters:
- StripPrefix=1
routes:
- id: R001
uri: http://localhost:8787
predicates:
- Path=/api-1/**,/api-2/**
metadata:
akf: "dbc"
#局部超時設置
connect-timeout: 10000
response-timeout: 5000
- id: st001
uri: lb://storage-service
predicates:
- Path=/api-x/**
- id: o001
uri: lb://order-service
predicates:
- Path=/api-a/**, /api-b/**
metadata:
akf: "dbc"
#局部超時設置
connect-timeout: 10000
response-timeout: 5000

訪問:??http://localhost:8088/api-1/demos??

轉換后:??http://localhost:8787/demos??

該過濾器最后會將轉換后的url保存到上下文中

ServerWebExchange#getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);

注意:上面的StripPrefixGatewayFilterFactory#apply過濾器執行完后,才會執行該過濾器。

總結:

訪問:
http://localhost:9090/api-x/orders ,路由地址:lb://order-service

  1. 轉換地址
    轉換后:http://localhost:9090/orders
  2. 合并地址
    將上一步的地址進一步合并為:lb://order-service/orders
    將地址存儲到上下文中:exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);

2 ReactiveLoadBalancerClientFilter

如果URL有一個lb(例如lb://order-service),它使用Spring Cloud ReactorLoadBalancer將名稱(在本例中為order-service)解析為一個實際的主機和端口,并替換相同屬性中的URI。?

public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
private final LoadBalancerClientFactory clientFactory;
private final GatewayLoadBalancerProperties properties;
private final LoadBalancerProperties loadBalancerProperties;


public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 從上下文中獲取,如:lb://order-service/orders
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
// preserve the original url
addOriginalRequestUrl(exchange, url);
// 再次獲取
URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
// 獲取服務名;order-service
String serviceId = requestUri.getHost();
// clientFactory.getInstances方法會從NamedContextFactory.contexts集合中查找以order-service為key對應的
// AnnotationConfigApplicationContext,然后從這個容器中查找LoadBalancerLifecycle,默認返回{}
// ------------------------------------------------------------
/**
* 每個服務對應的ApplicationContext包含如下13個Bean
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* org.springframework.context.annotation.internalCommonAnnotationProcessor
* org.springframework.context.event.internalEventListenerProcessor
* org.springframework.context.event.internalEventListenerFactory
* propertyPlaceholderAutoConfiguration loadBalancerClientConfiguration
* propertySourcesPlaceholderConfigurer
* LoadBalancerClientConfiguration$ReactiveSupportConfiguration
* discoveryClientServiceInstanceListSupplier
* LoadBalancerClientConfiguration$BlockingSupportConfiguration,
* reactorServiceInstanceLoadBalancer
*/
// 這里集合返回{}
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
.getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
RequestDataContext.class, ResponseData.class, ServiceInstance.class);
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(
new RequestData(exchange.getRequest()), getHint(serviceId, loadBalancerProperties.getHint())));
// choose負載查找指定服務(order-server)
return choose(lbRequest, serviceId, supportedLifecycleProcessors).doOnNext(response -> {
if (!response.hasServer()) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, response)));
throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());
}
ServiceInstance retrievedInstance = response.getServer();
URI uri = exchange.getRequest().getURI();
// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
// if the loadbalancer doesn't provide one.
String overrideScheme = retrievedInstance.isSecure() ? "https" : "http";
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(retrievedInstance, overrideScheme);
URI requestUrl = reconstructURI(serviceInstance, uri);
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
exchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response);
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, response));
}).then(chain.filter(exchange))
.doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.FAILED,
throwable, lbRequest, exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR)))))
.doOnSuccess(aVoid -> supportedLifecycleProcessors.forEach(
lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(
CompletionContext.Status.SUCCESS, lbRequest, exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR),
new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest()))))));
}


protected URI reconstructURI(ServiceInstance serviceInstance, URI original) {
return LoadBalancerUriTools.reconstructURI(serviceInstance, original);
}


private Mono<Response<ServiceInstance>> choose(Request<RequestDataContext> lbRequest, String serviceId,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors) {
// 從order-service對應的ApplicationContext中查找ReactorServiceInstanceLoadBalancer
ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance(serviceId,
ReactorServiceInstanceLoadBalancer.class);
if (loadBalancer == null) {
throw new NotFoundException("No loadbalancer available for " + serviceId);
}
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
// 查找服務實例
return loadBalancer.choose(lbRequest);
}


private String getHint(String serviceId, Map<String, String> hints) {
String defaultHint = hints.getOrDefault("default", "default");
String hintPropertyValue = hints.get(serviceId);
return hintPropertyValue != null ? hintPropertyValue : defaultHint;
}
}


// 輪詢算分
public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
final AtomicInteger position;
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;


public Mono<Response<ServiceInstance>> choose(Request request) {
// 接下面ClientFactoryObjectProvider中獲取ServiceInstanceListSupplier
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next().map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
}


private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances) {
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
}
return serviceInstanceResponse;
}


private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
return new EmptyResponse();
}
// TODO: enforce order?
int pos = Math.abs(this.position.incrementAndGet());
ServiceInstance instance = instances.get(pos % instances.size());
return new DefaultResponse(instance);
}
}


class ClientFactoryObjectProvider<T> implements ObjectProvider<T> {
private final NamedContextFactory<?> clientFactory;
// type = ServiceInstanceListSupplier
private final Class<T> type;
// name = order-service
private final String name;


private ObjectProvider<T> delegate() {
if (this.provider == null) {
// 從order-service對應ApplicationContext中獲取ServiceInstanceListSupplier
// 這里最終返回的是:DiscoveryClientServiceInstanceListSupplier
this.provider = this.clientFactory.getProvider(this.name, this.type);
}
return this.provider;
}
}


public class LoadBalancerClientConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnReactiveDiscoveryEnabled
@Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER)
public static class ReactiveSupportConfiguration {


@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "default", matchIfMissing = true)
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
// 這里最終構建的是:DiscoveryClientServiceInstanceListSupplier
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().build(context);
}
}
}


public final class ServiceInstanceListSupplierBuilder {
public ServiceInstanceListSupplierBuilder withDiscoveryClient() {
this.baseCreator = context -> {
// 先從order-service對應的ApplicationContext中查找ReactiveDiscoveryClient,如果你沒有自定義,那么就會從
// 父容器中查找,如果你使用的nacos,那么會返回NacosReactiveDiscoveryClient
ReactiveDiscoveryClient discoveryClient = context.getBean(ReactiveDiscoveryClient.class);
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment());
};
return this;
}
}

總結:

  1. 獲取地址
    獲取上一步中保存在上下文的地址
    URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
  2. 獲取LoadBalancerLifecycle
    取得當前服務(order-service),對應的AnnotationConfigApplicationContext中配置的LoadBalancerLifecycle,該負載均衡生命周期能夠監控負載均衡的執行過程。該類是泛型類,3個泛型參數,類型依次為:RequestDataContext.class, ResponseData.class, ServiceInstance.class。
  3. 獲取ReactorServiceInstanceLoadBalancer
    獲取當前服務(order-server),對應的AnnotationConfigApplicationContext中配置的ReactorServiceInstanceLoadBalancer。每一個服務都有一個對應的默認配置類LoadBalancerClientConfiguration,該配置類中有默認的RoundRobinLoadBalancer。我們可以為具體的服務提供LoadBalancerClientSpecification 類型的Bean,該類我們可以指定你要配置的serviceId及配置類,在配置類中我們可以自定義ReactorServiceInstanceLoadBalancer 的實現類Bean。
  4. 選擇服務
    在上一步中獲得ReactorServiceInstanceLoadBalancer后,接下來就是選取一個服務實例了。
  5. 重構URI
    上一步中獲取了ServiceInstance 后就能夠重構URL了,當前的URL為: http://localhost:9090/orders 構建后:http://localhost:9093/storages ,將該URL保存到上下文中 exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);

3 NettyRoutingFilter

public class NettyRoutingFilter implements GlobalFilter {
private final HttpClient httpClient;


public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 從上下文中獲取解析后的目標地址
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
// ...
// 獲取上下文中的路由信息
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// getHttpClient獲取客戶端信息
Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange).headers(headers -> {
// ...
}).request(method).uri(url).send((req, nettyOutbound) -> {
// 發送網絡請求
return nettyOutbound.send(request.getBody().map(this::getByteBuf));
}).responseConnection((res, connection) -> {
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
// 建立的Connection對象保存到上下文中,在后續的NettyWriteResponseFilter中會獲取該對象獲取響應數據
exchange.getAttributes().put(CLIENT_RESPONSE_CONN_ATTR, connection);
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = new HttpHeaders();
res.responseHeaders().forEach(entry -> headers.add(entry.getKey(), entry.getValue()));
String contentTypeValue = headers.getFirst(HttpHeaders.CONTENT_TYPE);
if (StringUtils.hasLength(contentTypeValue)) {
exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR, contentTypeValue);
}
setResponseStatus(res, response);
HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(getHeadersFilters(), headers, exchange,
Type.RESPONSE);
if (!filteredResponseHeaders.containsKey(HttpHeaders.TRANSFER_ENCODING)
&& filteredResponseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)) {
response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING);
}
exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES, filteredResponseHeaders.keySet());
response.getHeaders().putAll(filteredResponseHeaders);
return Mono.just(res);
});


// 從路由中的元數據中獲取response-timeout響應超時時間
Duration responseTimeout = getResponseTimeout(route);
if (responseTimeout != null) {
responseFlux = responseFlux
// 設置超時時間
.timeout(responseTimeout,
Mono.error(new TimeoutException("Response took longer than timeout: " + responseTimeout)))
.onErrorMap(TimeoutException.class,
th -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, th.getMessage(), th));
}
return responseFlux.then(chain.filter(exchange));
}


protected HttpClient getHttpClient(Route route, ServerWebExchange exchange) {
// 從路由的元數據中獲取配置的連接超時時間:connect-timeout
Object connectTimeoutAttr = route.getMetadata().get(CONNECT_TIMEOUT_ATTR);
if (connectTimeoutAttr != null) {
Integer connectTimeout = getInteger(connectTimeoutAttr);
// 設置Netty的連接超時時間
// io.netty.channel.ChannelOption
return this.httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
}
return httpClient;
}
}

總結:

  1. 獲取URL
    獲取上一步保存在上下文中的URL
    URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
  2. 設置當前路由狀態
    設置當前路由已經路由狀態
    setAlreadyRouted(exchange);
    exchange.getAttributes().put(GATEWAY_ALREADY_ROUTED_ATTR, true);
  3. 獲取路由
    Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
    獲取當前的Route信息。主要就用來獲取配置路由時提供的配置信息,比如:超時時間設置,如上配置。RoutePredicateHandlerMapping#getHandlerInternal方法中保存路由到上下文中
  4. 構建HttpClient
    通過上一步取得的Route對象,配置HttpClient相關屬性,比如:超時時間。配置基本的http相關信息,建立連接后將Connection對象保存到上下文中,供下一個過濾器獲取響應數據

4 NettyWriteResponseFilter

該過濾器的作用是處理由NettyRoutingFilter中建立的HTTP請求(包括:請求參數,請求頭,建立連接);在NettyRoutingFilter中會將建立連接后的Connection保存到ServerWebExchange上下文中。?

public class NettyWriteResponseFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_CONN_ATTR is not added
// until the NettyRoutingFilter is run
// @formatter:off
return chain.filter(exchange)
.doOnError(throwable -> cleanup(exchange))
.then(Mono.defer(() -> {
Connection connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR);
if (connection == null) {
return Mono.empty();
}
ServerHttpResponse response = exchange.getResponse();
// TODO: needed?
final Flux<DataBuffer> body = connection
.inbound()
.receive()
.retain()
.map(byteBuf -> wrap(byteBuf, response));
MediaType contentType = null;
try {
contentType = response.getHeaders().getContentType();
}
// 根據不同的ContentType做不同的響應
return (isStreamingMediaType(contentType)
? response.writeAndFlushWith(body.map(Flux::just))
: response.writeWith(body));
})).doOnCancel(() -> cleanup(exchange));
// @formatter:on
}


protected DataBuffer wrap(ByteBuf byteBuf, ServerHttpResponse response) {
DataBufferFactory bufferFactory = response.bufferFactory();
if (bufferFactory instanceof NettyDataBufferFactory) {
NettyDataBufferFactory factory = (NettyDataBufferFactory) bufferFactory;
return factory.wrap(byteBuf);
}
// MockServerHttpResponse creates these
else if (bufferFactory instanceof DefaultDataBufferFactory) {
DataBuffer buffer = ((DefaultDataBufferFactory) bufferFactory).allocateBuffer(byteBuf.readableBytes());
buffer.write(byteBuf.nioBuffer());
byteBuf.release();
return buffer;
}
throw new IllegalArgumentException("Unkown DataBufferFactory type " + bufferFactory.getClass());
}


private void cleanup(ServerWebExchange exchange) {
Connection connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR);
if (connection != null && connection.channel().isActive() && !connection.isPersistent()) {
connection.dispose();
}
}


private boolean isStreamingMediaType(@Nullable MediaType contentType) {
return (contentType != null && this.streamingMediaTypes.stream().anyMatch(contentType::isCompatibleWith));
}
}

總結:

  1. 取得Connection
    取得上一步中保存的Connection
    Connection connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR);
  2. 響應內容
    輸出微服務端響應的數據?
final Flux<DataBuffer> body = connection
.inbound()
.receive()
.retain()
.map(byteBuf -> wrap(byteBuf, response));

以上就是Gateway在處理一個路由請求的執行流程

完畢!!!

責任編輯:武曉燕 來源: 實戰案例錦集
相關推薦

2023-01-26 01:41:27

核心全局過濾器

2021-01-14 08:13:39

Spring Clou應用內置過濾器

2023-07-24 08:00:56

客戶端訪問指定

2024-04-03 08:08:15

謂詞網關開發

2017-04-12 14:43:01

Spring ClouZuul過濾器

2017-05-04 22:30:17

Zuul過濾器微服務

2023-02-15 08:12:19

http超時過濾器

2017-09-15 23:29:53

Spring Clou微服務架構過濾器

2009-07-08 16:07:04

Servlet過濾器配

2011-06-29 16:14:59

Qt 事件 過濾器

2016-12-07 09:56:13

JavaFilter過濾器

2024-12-06 14:34:00

Spring過濾器

2022-05-13 08:23:07

Zuul微服務Zuul過濾器

2023-05-04 08:09:33

serviceId路徑謂詞中心注冊

2021-07-05 15:22:03

Servlet過濾器客戶端

2024-01-05 09:04:35

隆過濾器數據結構哈希函數

2021-11-04 10:11:02

Sentinel網關限流

2020-03-27 08:46:51

微服務服務網關

2024-11-04 08:45:48

布隆過濾器元數據指紋值

2009-09-29 13:55:23

Hibernate設置
點贊
收藏

51CTO技術棧公眾號

91麻豆精品国产91久久久久久久久| 国产视频在线观看免费 | 日本韩国一区二区三区| 成人激情黄色网| 欧美深性狂猛ⅹxxx深喉 | 91午夜交换视频| 亚洲伊人春色| 国产成人av电影在线| 综合国产在线视频| 性生交免费视频| 神马精品久久| 一区二区免费| 亚洲天天做日日做天天谢日日欢| 欧洲成人午夜免费大片| 99精品一区二区三区无码吞精 | 日韩视频―中文字幕| 女人和拘做爰正片视频| 亚洲成人黄色片| 亚洲国产老妈| 欧美一级二级在线观看| 国产精品亚洲天堂| 一级视频在线播放| 99国产精品久久久久久久| 精品三级在线看| 少妇一晚三次一区二区三区| www三级免费| 韩国在线视频一区| 欧美va亚洲va国产综合| 欧美韩国日本在线| 国产高清自拍视频在线观看| 久久一区激情| 国产午夜一区二区| 亚洲老女人av| 福利在线视频网站| 国产成人8x视频一区二区| 国产精品福利久久久| 婷婷色一区二区三区 | 成人a视频在线观看| 亚洲永久精品在线观看| 欧美精美视频| 欧美三级蜜桃2在线观看| 一区二区三区国| 99视频在线观看免费| 欧美精品日本| 日韩精品中文字幕在线观看| 超碰影院在线观看| 色欧美激情视频在线| 国产精品综合av一区二区国产馆| 欧美日本国产在线| 国产精品嫩草av| 亚洲网一区二区三区| 91精品欧美一区二区三区综合在| 手机在线看福利| 成人免费看视频网站| 中文字幕二三区不卡| 91精品国自产在线观看| 亚洲精品www久久久久久| 精品国产一区探花在线观看| 欧美一区二区三区的| 欧美久久久久久久久久久久久| 日韩a在线观看| 激情成人综合网| 97精品视频在线播放| 国产一区二区三区四区在线| 欧美一区在线观看视频| 欧美体内谢she精2性欧美| 亚洲午夜精品福利| 免费在线你懂的| 91在线porny国产在线看| 国产免费一区二区三区在线观看| 久草视频免费在线播放| 精品久久久久久久久久久下田| 精品在线观看国产| 国产全是老熟女太爽了| 99精品中文字幕在线不卡| 欧美亚洲国产怡红院影院| 青青在线视频免费观看| 2019中文字幕在线电影免费| 中文字幕av一区二区三区| 亚洲欧美国产精品桃花| 无码精品一区二区三区在线| 激情久久五月天| 成人免费在线看片| 在线观看中文字幕2021| 亚洲在线成人| 欧美高清电影在线看| 免费看91的网站| 麻豆一区一区三区四区| 91精品国产综合久久久久久久久久| 一级做a免费视频| 精品视频一区二区三区四区五区| 亚洲午夜av在线| 穿情趣内衣被c到高潮视频| se在线电影| 久久蜜桃av一区二区天堂| 粉嫩av免费一区二区三区| 婷婷国产在线| 中文字幕一区二区三区乱码在线| 欧美日本国产精品| 天天操天天干天天操| 国产成人在线观看| 91精品视频一区| 国产一区二区小视频| 成人免费视频播放| 电影午夜精品一区二区三区| 免费观看成年在线视频网站| 99精品热视频| av动漫免费观看| 欧美aa在线观看| 午夜欧美在线一二页| 蜜臀av色欲a片无码精品一区| av在线免费网站| 欧美日韩一区免费| 国产免费观看高清视频| av岛国在线| 欧美日韩高清一区二区| 国产探花在线看| 欧美男人操女人视频| 亚洲第一男人av| 国产视频精品视频| 久久国产成人午夜av影院宅| 最新中文字幕亚洲| 黄色一级大片在线免费观看| 久久久久久久久国产一区| 欧美在线一区二区视频| 精品人妻无码一区二区色欲产成人 | 超碰福利在线观看| 日本一区二区视频在线观看| 日本欧洲国产一区二区| 超碰免费97在线观看| 亚洲国产精品久久一线不卡| 欧美一级片免费播放| av电影免费在线看| 91精品福利在线一区二区三区| 久久精品国产亚洲av麻豆| 国产欧美日韩一区二区三区四区| 夜夜嗨av色一区二区不卡| 神马久久久久久久久久久| 日韩亚洲国产精品| dy888夜精品国产专区| 少妇精品高潮欲妇又嫩中文字幕| 国产精品成人网| 久久久国产欧美| 美女精品一区最新中文字幕一区二区三区 | 日韩电影免费在线看| 国产精品一区久久久| 三级av在线| 精品欧美一区二区三区| 麻豆精品国产传媒av| 免费成人结看片| 欧美中文在线免费| 青青久草在线| 日韩欧美中文第一页| 亚洲av网址在线| 先锋影音久久| 欧美亚洲另类久久综合| 欧美成人资源| 欧美一级搡bbbb搡bbbb| 天天鲁一鲁摸一摸爽一爽| 国产综合色视频| 精品日本一区二区| 91大神在线网站| 亚洲成人精品一区二区| 亚洲欧美综合视频| 国产欧美日韩精品一区二区三区 | 最近中文字幕在线观看| 狠狠色狠狠色合久久伊人| 亚洲一区3d动漫同人无遮挡 | 日本网站在线观看一区二区三区| 成人精品一区二区三区电影免费| 幼a在线观看| 欧美高清一级片在线| 一级特级黄色片| 国产精品女主播一区二区三区| 国产原创欧美精品| 欧美 日韩 人妻 高清 中文| 久久亚洲一级片| 成人免费无码av| 日本电影一区二区| 97婷婷涩涩精品一区| 香蕉av在线播放| 91黄视频在线| 日韩a级片在线观看| 国产欧美不卡| 日韩中文字幕一区| 成人三级小说| 欧美一级日韩免费不卡| 日本三级午夜理伦三级三| 日韩avvvv在线播放| 伊人天天久久大香线蕉av色| 日韩脚交footjobhdboots| 亚洲欧洲激情在线| 圆产精品久久久久久久久久久| 91麻豆福利精品推荐| 日本香蕉视频在线观看| aa亚洲一区一区三区| 一区二区欧美久久| 国产夫绿帽单男3p精品视频| 天天影视涩香欲综合网| 一区二区三区四区影院| 免费日韩av片| 强伦女教师2:伦理在线观看| 黄色成人美女网站| 国产精品欧美激情| 青青视频在线观| 91精品国产综合久久久蜜臀粉嫩 | 中文亚洲欧美| 在线视频欧美一区| 色88888久久久久久影院| 午夜精品一区二区三区在线视 | 精品久久对白| 成人免费视频网址| 成人教育av| 性欧美在线看片a免费观看| 在线观看黄av| 日韩不卡中文字幕| www日韩精品| 亚洲欧美综合在线精品| 午夜国产福利在线观看| 99九九热只有国产精品| 91最新在线免费观看| 在线视频国产区| 亚洲第一av在线| 国产精品熟女久久久久久| 亚洲男人电影天堂| 麻豆tv在线观看| 在线视频日韩| 91视频 - 88av| 天天插综合网| 午夜精品一区二区在线观看 | 在线欧美一区| 精品欧美国产| 亚洲日本一区二区三区在线| 成人免费激情视频| 九七影院97影院理论片久久| 久久色精品视频| 国产情侣小视频| 国产精品成人免费| 免费看黄色的视频| 91尤物视频在线观看| 图片区偷拍区小说区| 国产在线看一区| 中文字幕亚洲欧洲| 久久99蜜桃精品| 青青草视频在线视频| 欧美成人日本| 欧美极品一区二区| 小说区图片区色综合区| 久久av免费一区| 黄色成人小视频| 国产精品黄页免费高清在线观看| 亚洲最大成人| 国产91露脸中文字幕在线| 欧美性天天影视| 中文字幕成人精品久久不卡| 国产精品99999| 中文字幕精品网| 男人的天堂在线视频免费观看 | 人妻互换一区二区激情偷拍| 国产精品一区二区果冻传媒| 中文字幕在线视频一区二区三区 | 丁香婷婷激情网| 中文字幕一区二区三三| 欧美极品色图| 精品大片一区二区| 一区不卡视频| 欧美+亚洲+精品+三区| 亚洲熟妇无码av在线播放| 激情久久久久久| 97av视频在线观看| 免费人成网站在线观看欧美高清| 日本天堂免费a| 亚洲人成免费| avove在线观看| 欧美日一区二区在线观看 | 天天做夜夜爱爱爱| 91色在线porny| 精品一区二区三区蜜桃在线| 综合久久久久综合| 黄色激情视频在线观看| 色一情一乱一乱一91av| 国产亚洲精品久久久久久无几年桃| 中文字幕不卡在线播放| 男人在线观看视频| 亚洲第一在线综合网站| 尤物视频免费观看| 欧美日韩国产在线| 看黄色一级大片| 日韩丝袜情趣美女图片| 香蕉国产在线视频| 久久精品99无色码中文字幕 | 亚洲成人av一区| 中文字幕av影院| 天天av天天翘天天综合网色鬼国产| 日韩色图在线观看| 欧美顶级少妇做爰| 亚洲色欧美另类| 久久久www成人免费精品| 麻豆国产在线| 国产啪精品视频网站| 国语一区二区三区| 成人xxxxx色| 青青草原综合久久大伊人精品 | 丁香六月综合| 91青草视频久久| 精品影片在线观看的网站| 女女百合国产免费网站| 97精品国产福利一区二区三区| 日韩和欧美的一区二区| 中文字幕一区二区三区乱码图片 | 亚洲欧美日韩不卡| 亚洲在线视频| 成人三级做爰av| 国产精品77777竹菊影视小说| 日韩精品电影一区二区| 亚洲综合色网站| 国产成人精品av久久| 亚洲一级二级三级| 在线观看免费视频a| 日韩国产在线播放| 欧美人与性动交α欧美精品济南到| 久久国产精品久久国产精品| a黄色片在线观看| 国产精品吹潮在线观看| 久久丝袜视频| 欧美激情亚洲天堂| 国产一区二区三区精品欧美日韩一区二区三区 | 日本韩国欧美一区二区三区| 国产黄a三级三级看三级| 中文字幕国产亚洲| 欧美www.| 美女被啪啪一区二区| 亚洲国产91视频| 91传媒在线免费观看| 欧美jizz| 天天干天天干天天干天天干天天干| 91首页免费视频| 午夜精品久久久久久久久久久久久蜜桃| 精品毛片三在线观看| www.亚洲黄色| 久久成人人人人精品欧| www.久久草.com| 精品日韩在线播放| 精品一区二区三区视频 | 天天影院图片亚洲| 欧美在线视频网| 中文字幕中文字幕精品| 日本熟妇人妻xxxxx| 91免费看`日韩一区二区| 四虎成人永久免费视频| 精品视频一区在线视频| 在线免费av资源| 国产精品爽爽爽| 成人aaaa| 午夜免费看视频| 99视频在线精品| 国产精品视频看看| 午夜精品久久久久久久久久 | 天堂中文字幕在线观看| 亚洲精品小视频在线观看| 免费观看欧美大片| 亚洲一区二区三区精品动漫| 韩国精品免费视频| 国产一级二级三级| 亚洲精品99久久久久| 精品视频在线一区二区| 国产91对白在线播放| 久久综合给合| 色一情一乱一伦一区二区三欧美 | 一区视频在线| 亚洲欧美色图视频| 一区二区三区不卡在线观看| 亚洲毛片在线播放| 久久久99久久精品女同性| 亚洲视频一起| 久久精品视频91| 亚洲美女视频在线观看| 少妇高潮一区二区三区69| 国产精品福利在线观看| 欧美在线高清| 在线免费观看日韩av| 欧美猛男gaygay网站| 久久不射影院| 五月天婷亚洲天综合网鲁鲁鲁| 国产自产2019最新不卡| 日本视频免费观看| 久国内精品在线| 欧美**vk| 91传媒理伦片在线观看| 欧洲一区二区三区在线| 四虎影院在线播放| 成人欧美在线视频| 国产精品日韩精品欧美精品| 91精品一区二区三区蜜桃| 精品亚洲精品福利线在观看| 欧美性生活一级| 欧美激情视频免费看| 中文字幕二三区不卡| 99re只有精品| 国产99久久精品一区二区 夜夜躁日日躁 |