日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

SpringCloud gateway 在實(shí)現(xiàn)服務(wù)路由并請求的具體過程是在 org.springframework.cloud.gateway.filter.NETtyRoutingFilter 的過濾器中,該過濾器封裝了具體的請求參數(shù),以及根據(jù)路由規(guī)則請求的對應(yīng)服務(wù),然后根據(jù) HttpClient 進(jìn)行微服務(wù)之間的請求; 該 httpClient 類是 用netty 封裝的 客戶端,其包路徑為 : reactor.netty.http.client.HttpClient ;

  查看 NettyRoutingFilter 中的 filter 實(shí)現(xiàn)過程:

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        URI requestUrl = (URI)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        String scheme = requestUrl.getScheme();        if (!ServerWebExchangeUtils.isAlreadyRouted(exchange) && ("http".equals(scheme) || "https".equals(scheme))) {            ServerWebExchangeUtils.setAlreadyRouted(exchange);            ServerHttpRequest request = exchange.getRequest();            HttpMethod method = HttpMethod.valueOf(request.getMethodValue());            String url = requestUrl.toASCIIString();            HttpHeaders filtered = HttpHeadersFilter.filterRequest(this.getHeadersFilters(), exchange);            DefaultHttpHeaders httpHeaders = new DefaultHttpHeaders();            filtered.forEach(httpHeaders::set);            boolean preserveHost = (Boolean)exchange.getAttributeOrDefault(ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE, false);            Route route = (Route)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);            Flux<HttpClientResponse> responseFlux = ((RequestSender)this.getHttpClient(route, exchange).headers((headers) -> {                headers.add(httpHeaders);                headers.remove("Host");                if (preserveHost) {                    String host = request.getHeaders().getFirst("Host");                    headers.add("Host", host);                }            }).request(method).uri(url)).send((req, nettyOutbound) -> {                if (log.isTraceEnabled()) {                    nettyOutbound.withConnection((connection) -> {                        log.trace("outbound route: " + connection.channel().id().asShortText() + ", inbound: " + exchange.getLogPrefix());                    });                }                return nettyOutbound.send(request.getBody().map(this::getByteBuf));            }).responseConnection((res, connection) -> {                exchange.getAttributes().put(ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR, res);                exchange.getAttributes().put(ServerWebExchangeUtils.CLIENT_RESPONSE_CONN_ATTR, connection);                ServerHttpResponse response = exchange.getResponse();                HttpHeaders headers = new HttpHeaders();                res.responseHeaders().forEach((entry) -> {                    headers.add((String)entry.getKey(), (String)entry.getValue());                });                String contentTypeValue = headers.getFirst("Content-Type");                if (StringUtils.hasLength(contentTypeValue)) {                    exchange.getAttributes().put("original_response_content_type", contentTypeValue);                }                this.setResponseStatus(res, response);                HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(this.getHeadersFilters(), headers, exchange, Type.RESPONSE);                if (!filteredResponseHeaders.containsKey("Transfer-Encoding") && filteredResponseHeaders.containsKey("Content-Length")) {                    response.getHeaders().remove("Transfer-Encoding");                }                exchange.getAttributes().put(ServerWebExchangeUtils.CLIENT_RESPONSE_HEADER_NAMES, filteredResponseHeaders.keySet());                response.getHeaders().putAll(filteredResponseHeaders);                return Mono.just(res);            });            Duration responseTimeout = this.getResponseTimeout(route);            if (responseTimeout != null) {                responseFlux = responseFlux.timeout(responseTimeout, Mono.error(new TimeoutException("Response took longer than timeout: " + responseTimeout))).onErrorMap(TimeoutException.class, (th) -> {                    return new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, th.getMessage(), th);                });            }            return responseFlux.then(chain.filter(exchange));        } else {            return chain.filter(exchange);        }    }

 

  該方法中 有一個 getHttpClient 方法獲取 httpClient 客戶端實(shí)例的過程,由于在 GatewayAutoConfiguration 中 定義了 springCloud gateway 使用的 httpclient 實(shí)例,其聲明并自動加載的代碼如下:

@Configuration(        proxyBeanMethods = false    )    @ConditionalOnClass({HttpClient.class})    protected static class NettyConfiguration {        protected final Log logger = LogFactory.getLog(this.getClass());        protected NettyConfiguration() {        }        @Bean        @ConditionalOnProperty(            name = {"spring.cloud.gateway.httpserver.wiretap"}        )        public NettyWebServerFactoryCustomizer nettyServerWiretapCustomizer(Environment environment, ServerProperties serverProperties) {            return new NettyWebServerFactoryCustomizer(environment, serverProperties) {                public void customize(NettyReactiveWebServerFactory factory) {                    factory.addServerCustomizers(new NettyServerCustomizer[]{(httpServer) -> {                        return httpServer.wiretap(true);                    }});                    super.customize(factory);                }            };        }        @Bean        @ConditionalOnMissingBean        public HttpClient gatewayHttpClient(HttpClientProperties properties, List<HttpClientCustomizer> customizers) {            Pool pool = properties.getPool();            ConnectionProvider connectionProvider;            if (pool.getType() == PoolType.DISABLED) {                connectionProvider = ConnectionProvider.newConnection();            } else if (pool.getType() == PoolType.FIXED) {                connectionProvider = ConnectionProvider.fixed(pool.getName(), pool.getMaxConnections(), pool.getAcquireTimeout(), pool.getMaxIdleTime(), pool.getMaxLifeTime());            } else {                connectionProvider = ConnectionProvider.elastic(pool.getName(), pool.getMaxIdleTime(), pool.getMaxLifeTime());            }            HttpClient httpClient = HttpClient.create(connectionProvider).httpResponseDecoder((spec) -> {                if (properties.getMaxHeaderSize() != null) {                    spec.maxHeaderSize((int)properties.getMaxHeaderSize().toBytes());                }                if (properties.getMaxInitialLineLength() != null) {                    spec.maxInitialLineLength((int)properties.getMaxInitialLineLength().toBytes());                }                return spec;            }).tcpConfiguration((tcpClient) -> {                if (properties.getConnectTimeout() != null) {                    tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());                }                Proxy proxy = properties.getProxy();                if (StringUtils.hasText(proxy.getHost())) {                    tcpClient = tcpClient.proxy((proxySpec) -> {                        Builder builder = proxySpec.type(reactor.netty.tcp.ProxyProvider.Proxy.HTTP).host(proxy.getHost());                        PropertyMApper map = PropertyMapper.get();                        proxy.getClass();                        map.from(proxy::getPort).whenNonNull().to(builder::port);                        proxy.getClass();                        map.from(proxy::getUsername).whenHasText().to(builder::username);                        proxy.getClass();                        map.from(proxy::getPassword).whenHasText().to((password) -> {                            builder.password((s) -> {                                return password;                            });                        });                        proxy.getClass();                        map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);                    });                }                return tcpClient;            });            Ssl ssl = properties.getSsl();            if (ssl.getKeyStore() != null && ssl.getKeyStore().length() > 0 || ssl.getTrustedX509CertificatesForTrustManager().length > 0 || ssl.isUseInsecureTrustManager()) {                httpClient = httpClient.secure((sslContextSpec) -> {                    SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();                    X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();                    if (trustedX509Certificates.length > 0) {                        sslContextBuilder = sslContextBuilder.trustManager(trustedX509Certificates);                    } else if (ssl.isUseInsecureTrustManager()) {                        sslContextBuilder = sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);                    }                    try {                        sslContextBuilder = sslContextBuilder.keyManager(ssl.getKeyManagerFactory());                    } catch (Exception var6) {                        this.logger.error(var6);                    }                    sslContextSpec.sslContext(sslContextBuilder).defaultConfiguration(ssl.getDefaultConfigurationType()).handshakeTimeout(ssl.getHandshakeTimeout()).closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout()).closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());                });            }            if (properties.isWiretap()) {                httpClient = httpClient.wiretap(true);            }            if (!CollectionUtils.isEmpty(customizers)) {                customizers.sort(AnnotationAwareOrderComparator.INSTANCE);                HttpClientCustomizer customizer;                for(Iterator var7 = customizers.iterator(); var7.hasNext(); httpClient = customizer.customize(httpClient)) {                    customizer = (HttpClientCustomizer)var7.next();                }            }            return httpClient;        }        @Bean        public HttpClientProperties httpClientProperties() {            return new HttpClientProperties();        }        @Bean        public NettyRoutingFilter routingFilter(HttpClient httpClient, ObjectProvider<List<HttpHeadersFilter>> headersFilters, HttpClientProperties properties) {            return new NettyRoutingFilter(httpClient, headersFilters, properties);        }        @Bean        public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {            return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());        }        @Bean        public ReactorNettyWebSocketClient reactorNettyWebSocketClient(HttpClientProperties properties, HttpClient httpClient) {            ReactorNettyWebSocketClient webSocketClient = new ReactorNettyWebSocketClient(httpClient);            if (properties.getWebsocket().getMaxFramePayloadLength() != null) {                webSocketClient.setMaxFramePayloadLength(properties.getWebsocket().getMaxFramePayloadLength());            }            webSocketClient.setHandlePing(properties.getWebsocket().isProxyPing());            return webSocketClient;        }        @Bean        public ReactorNettyRequestUpgradeStrategy reactorNettyRequestUpgradeStrategy(HttpClientProperties httpClientProperties) {            ReactorNettyRequestUpgradeStrategy requestUpgradeStrategy = new ReactorNettyRequestUpgradeStrategy();            Websocket websocket = httpClientProperties.getWebsocket();            PropertyMapper map = PropertyMapper.get();            websocket.getClass();            map.from(websocket::getMaxFramePayloadLength).whenNonNull().to(requestUpgradeStrategy::setMaxFramePayloadLength);            websocket.getClass();            map.from(websocket::isProxyPing).to(requestUpgradeStrategy::setHandlePing);            return requestUpgradeStrategy;        }    }

  上面 代碼中的 gatewayHttpClient 為 spring cloud gateway 使用的 HttpClient 實(shí)例,在spring cloud gateway 進(jìn)行服務(wù)請求時,會自動配置使用該 實(shí)例。

  如果需要自定義的 HttpClient 實(shí)例,如在 httpClient 中自定義 ip 白名單校驗(yàn),https 請求證書預(yù)置,或是添加特殊認(rèn)證請求頭等,這種場景下需要在代碼中顯示的定義 gatewayHttpClient 實(shí)例,代碼如下:

    @Configuration    public class GatewayAutoConfiguration {        @Bean        @ConditionalOnMissingBean        public HttpClient gatewayHttpClient(HttpClientProperties properties, List<HttpClientCustomizer> customizers) {            Pool pool = properties.getPool();            ConnectionProvider connectionProvider;            if (pool.getType() == PoolType.DISABLED) {                connectionProvider = ConnectionProvider.newConnection();            } else if (pool.getType() == PoolType.FIXED) {                connectionProvider = ConnectionProvider.fixed(pool.getName(), pool.getMaxConnections(), pool.getAcquireTimeout(), pool.getMaxIdleTime(), pool.getMaxLifeTime());            } else {                connectionProvider = ConnectionProvider.elastic(pool.getName(), pool.getMaxIdleTime(), pool.getMaxLifeTime());            }            HttpClient httpClient = HttpClient.create(connectionProvider).httpResponseDecoder((spec) -> {                if (properties.getMaxHeaderSize() != null) {                    spec.maxHeaderSize((int)properties.getMaxHeaderSize().toBytes());                }                if (properties.getMaxInitialLineLength() != null) {                    spec.maxInitialLineLength((int)properties.getMaxInitialLineLength().toBytes());                }                return spec;            }).tcpConfiguration((tcpClient) -> {                if (properties.getConnectTimeout() != null) {                    tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());                }                Proxy proxy = properties.getProxy();                if (StringUtils.hasText(proxy.getHost())) {                    tcpClient = tcpClient.proxy((proxySpec) -> {                        Builder builder = proxySpec.type(reactor.netty.tcp.ProxyProvider.Proxy.HTTP).host(proxy.getHost());                        PropertyMapper map = PropertyMapper.get();                        proxy.getClass();                        map.from(proxy::getPort).whenNonNull().to(builder::port);                        proxy.getClass();                        map.from(proxy::getUsername).whenHasText().to(builder::username);                        proxy.getClass();                        map.from(proxy::getPassword).whenHasText().to((password) -> {                            builder.password((s) -> {                                return password;                            });                        });                        proxy.getClass();                        map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);                    });                }                return tcpClient;            });            Ssl ssl = properties.getSsl();            if (ssl.getKeyStore() != null && ssl.getKeyStore().length() > 0 || ssl.getTrustedX509CertificatesForTrustManager().length > 0 || ssl.isUseInsecureTrustManager()) {                httpClient = httpClient.secure((sslContextSpec) -> {                    SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();                    X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();                    if (trustedX509Certificates.length > 0) {                        sslContextBuilder = sslContextBuilder.trustManager(trustedX509Certificates);                    } else if (ssl.isUseInsecureTrustManager()) {                        sslContextBuilder = sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);                    }                    try {                        sslContextBuilder = sslContextBuilder.keyManager(ssl.getKeyManagerFactory());                    } catch (Exception var6) {                        this.logger.error(var6);                    }                    sslContextSpec.sslContext(sslContextBuilder).defaultConfiguration(ssl.getDefaultConfigurationType()).handshakeTimeout(ssl.getHandshakeTimeout()).closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout()).closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());                });            }            if (properties.isWiretap()) {                httpClient = httpClient.wiretap(true);            }            if (!CollectionUtils.isEmpty(customizers)) {                customizers.sort(AnnotationAwareOrderComparator.INSTANCE);                HttpClientCustomizer customizer;                for(Iterator var7 = customizers.iterator(); var7.hasNext(); httpClient = customizer.customize(httpClient)) {                    customizer = (HttpClientCustomizer)var7.next();                }            }            return httpClient;        }            }    

   這樣服務(wù)在啟動的時候就會優(yōu)先加載自定的 httpClient 實(shí)例。

原文鏈接:
https://www.cnblogs.com/zjdxr-up/p/16530423.html

分享到:
標(biāo)簽:httpClient
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定