首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊spring cloud gateway的NettyConfiguration

聊聊spring cloud gateway的NettyConfiguration

作者头像
code4it
发布2018-09-17 16:47:48
1.9K0
发布2018-09-17 16:47:48
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究下spring cloud gateway的NettyConfiguration

NettyConfiguration

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {

    @Configuration
    @ConditionalOnClass(HttpClient.class)
    protected static class NettyConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
            return HttpClient.create(options);
        }

        @Bean
        public Consumer<? super HttpClientOptions.Builder> nettyClientOptions(HttpClientProperties properties) {
            return opts -> {

                // configure ssl
                HttpClientProperties.Ssl ssl = properties.getSsl();

                if (ssl.isUseInsecureTrustManager()) {
                    opts.sslSupport(sslContextBuilder -> {
                        sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
                    });
                }

                // configure pool resources
                HttpClientProperties.Pool pool = properties.getPool();

                if (pool.getType() == DISABLED) {
                    opts.disablePool();
                } else if (pool.getType() == FIXED) {
                    PoolResources poolResources = PoolResources.fixed(pool.getName(),
                            pool.getMaxConnections(), pool.getAcquireTimeout());
                    opts.poolResources(poolResources);
                } else {
                    PoolResources poolResources = PoolResources.elastic(pool.getName());
                    opts.poolResources(poolResources);
                }

                // configure proxy if proxy host is set.
                HttpClientProperties.Proxy proxy = properties.getProxy();
                if (StringUtils.hasText(proxy.getHost())) {
                    opts.proxy(typeSpec -> {
                        ClientProxyOptions.Builder builder = typeSpec
                                .type(ClientProxyOptions.Proxy.HTTP)
                                .host(proxy.getHost());

                        PropertyMapper map = PropertyMapper.get();

                        map.from(proxy::getPort)
                                .whenNonNull()
                                .to(builder::port);
                        map.from(proxy::getUsername)
                                .whenHasText()
                                .to(builder::username);
                        map.from(proxy::getPassword)
                                .whenHasText()
                                .to(password -> builder.password(s -> password));
                        map.from(proxy::getNonProxyHostsPattern)
                                .whenHasText()
                                .to(builder::nonProxyHosts);

                        return builder;
                    });
                }
            };
        }

        @Bean
        public HttpClientProperties httpClientProperties() {
            return new HttpClientProperties();
        }

        @Bean
        public NettyRoutingFilter routingFilter(HttpClient httpClient,
                                                ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
            return new NettyRoutingFilter(httpClient, headersFilters);
        }

        @Bean
        public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
            return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
        }

        @Bean
        public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
            return new ReactorNettyWebSocketClient(options);
        }
    }
    //......
}

spring cloud gateway使用的是reactor的httpclient,其通过nettyClientOptions这个bean来进行构造options,具体的配置是HttpClientProperties

HttpClientProperties

配置说明

   {
      "sourceType": "org.springframework.cloud.gateway.config.HttpClientProperties",
      "name": "spring.cloud.gateway.httpclient",
      "type": "org.springframework.cloud.gateway.config.HttpClientProperties"
    },
    {
      "sourceType": "org.springframework.cloud.gateway.config.HttpClientProperties",
      "name": "spring.cloud.gateway.httpclient.pool",
      "sourceMethod": "getPool()",
      "type": "org.springframework.cloud.gateway.config.HttpClientProperties$Pool"
    },
    {
      "sourceType": "org.springframework.cloud.gateway.config.HttpClientProperties",
      "name": "spring.cloud.gateway.httpclient.proxy",
      "sourceMethod": "getProxy()",
      "type": "org.springframework.cloud.gateway.config.HttpClientProperties$Proxy"
    },
    {
      "sourceType": "org.springframework.cloud.gateway.config.HttpClientProperties",
      "name": "spring.cloud.gateway.httpclient.ssl",
      "sourceMethod": "getSsl()",
      "type": "org.springframework.cloud.gateway.config.HttpClientProperties$Ssl"
    }

可以看到主要是pool、proxy、ssl这几个配置

配置类

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/HttpClientProperties.java

@ConfigurationProperties("spring.cloud.gateway.httpclient")
public class HttpClientProperties {

    /** Pool configuration for Netty HttpClient */
    private Pool pool = new Pool();

    /** Proxy configuration for Netty HttpClient */
    private Proxy proxy = new Proxy();

    /** SSL configuration for Netty HttpClient */
    private Ssl ssl = new Ssl();

    //......

    @Override
    public String toString() {
        return "HttpClientProperties{" +
                "pool=" + pool +
                ", proxy=" + proxy +
                '}';
    }
}

Pool

    public static class Pool {

        public enum PoolType { ELASTIC, FIXED, DISABLED }

        /** Type of pool for HttpClient to use, defaults to ELASTIC. */
        private PoolType type = PoolType.ELASTIC;

        /** The channel pool map name, defaults to proxy. */
        private String name = "proxy";

        /** Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones. */
        private Integer maxConnections = PoolResources.DEFAULT_POOL_MAX_CONNECTION;

        /** Only for type FIXED, the maximum time in millis to wait for aquiring. */
        private Long acquireTimeout = PoolResources.DEFAULT_POOL_ACQUIRE_TIMEOUT;

        //......

        @Override
        public String toString() {
            return "Pool{" +
                    "type=" + type +
                    ", name='" + name + '\'' +
                    ", maxConnections=" + maxConnections +
                    ", acquireTimeout=" + acquireTimeout +
                    '}';
        }
    }

一共可以指定如下几个属性

  • spring.cloud.gateway.httpclient.pool.type,默认是ELASTIC
  • spring.cloud.gateway.httpclient.pool.name,默认是proxy

如果type是fixed类型,还可以指定如下两个参数

  • spring.cloud.gateway.httpclient.pool.maxConnections,默认是PoolResources.DEFAULT_POOL_MAX_CONNECTION /** * Default max connection, if -1 will never wait to acquire before opening new * connection in an unbounded fashion. Fallback to * available number of processors. */ int DEFAULT_POOL_MAX_CONNECTION = Integer.parseInt(System.getProperty("reactor.ipc.netty.pool.maxConnections", "" + Math.max(Runtime.getRuntime() .availableProcessors(), 8) * 2));
  • spring.cloud.gateway.httpclient.pool.acquireTimeout,默认是PoolResources.DEFAULT_POOL_ACQUIRE_TIMEOUT /** * Default acquisition timeout before error. If -1 will never wait to * acquire before opening new * connection in an unbounded fashion. Fallback to * available number of processors. */ long DEFAULT_POOL_ACQUIRE_TIMEOUT = Long.parseLong(System.getProperty( "reactor.ipc.netty.pool.acquireTimeout", "" + 45000));

Proxy

    public class Proxy {
        /** Hostname for proxy configuration of Netty HttpClient. */
        private String host;
        /** Port for proxy configuration of Netty HttpClient. */
        private Integer port;
        /** Username for proxy configuration of Netty HttpClient. */
        private String username;
        /** Password for proxy configuration of Netty HttpClient. */
        private String password;
        /** Regular expression (Java) for a configured list of hosts
         * that should be reached directly, bypassing the proxy */
        private String nonProxyHostsPattern;

        //......

        @Override
        public String toString() {
            return "Proxy{" +
                    "host='" + host + '\'' +
                    ", port=" + port +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", nonProxyHostsPattern='" + nonProxyHostsPattern + '\'' +
                    '}';
        }
    }

可以配置如下几个参数

  • spring.cloud.gateway.httpclient.proxy.host
  • spring.cloud.gateway.httpclient.proxy.port
  • spring.cloud.gateway.httpclient.proxy.username
  • spring.cloud.gateway.httpclient.proxy.password
  • spring.cloud.gateway.httpclient.proxy.nonProxyHostsPattern

Ssl

    public class Ssl {
        /** Installs the netty InsecureTrustManagerFactory. This is insecure and not suitable for production. */
        private boolean useInsecureTrustManager = false;

        //TODO: support configuration of other trust manager factories

        public boolean isUseInsecureTrustManager() {
            return useInsecureTrustManager;
        }

        public void setUseInsecureTrustManager(boolean useInsecureTrustManager) {
            this.useInsecureTrustManager = useInsecureTrustManager;
        }

        @Override
        public String toString() {
            return "Ssl{" +
                    "useInsecureTrustManager=" + useInsecureTrustManager +
                    '}';
        }
    }

主要是配置spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager属性,设置为true的话,则会使用InsecureTrustManagerFactory.INSTANCE

netty-handler-4.1.23.Final-sources.jar!/io/netty/handler/ssl/util/InsecureTrustManagerFactory.java

/**
 * An insecure {@link TrustManagerFactory} that trusts all X.509 certificates without any verification.
 * <p>
 * <strong>NOTE:</strong>
 * Never use this {@link TrustManagerFactory} in production.
 * It is purely for testing purposes, and thus it is very insecure.
 * </p>
 */
public final class InsecureTrustManagerFactory extends SimpleTrustManagerFactory {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(InsecureTrustManagerFactory.class);

    public static final TrustManagerFactory INSTANCE = new InsecureTrustManagerFactory();

    private static final TrustManager tm = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String s) {
            logger.debug("Accepting a client certificate: " + chain[0].getSubjectDN());
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String s) {
            logger.debug("Accepting a server certificate: " + chain[0].getSubjectDN());
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return EmptyArrays.EMPTY_X509_CERTIFICATES;
        }
    };

    private InsecureTrustManagerFactory() { }

    @Override
    protected void engineInit(KeyStore keyStore) throws Exception { }

    @Override
    protected void engineInit(ManagerFactoryParameters managerFactoryParameters) throws Exception { }

    @Override
    protected TrustManager[] engineGetTrustManagers() {
        return new TrustManager[] { tm };
    }
}

小结

spring cloud gateway底层使用的是reactor的httpclient,可以通过spring.cloud.gateway.httpclient前缀的配置来指定相关options。主要分pool、proxy、ssl三大类。其中pool默认的type是elastic,如果是fixed的话,还可以指定maxConnections及acquireTimeout参数。

doc

  • Part XV. Spring Cloud Gateway
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NettyConfiguration
  • HttpClientProperties
    • 配置说明
      • 配置类
      • Pool
      • Proxy
      • Ssl
      • 小结
      • doc
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档