ConnPoolControl
针对链接池的配置,查看源码可以看到主要在这个接口中。
package org.apache.http.pool; /** * Interface to control runtime properties of a {@link ConnPool} such as * maximum total number of connections or maximum connections per route * allowed. * * @param <T> the route type that represents the opposite endpoint of a pooled * connection. * @since 4.2 */ public interface ConnPoolControl<T> { void setMaxTotal(int max); int getMaxTotal(); void setDefaultMaxPerRoute(int max); int getDefaultMaxPerRoute(); void setMaxPerRoute(final T route, int max); int getMaxPerRoute(final T route); PoolStats getTotalStats(); PoolStats getStats(final T route); }
配置项
- 上面提到的路由指的是按主机对MaxTotal进行再分配。比如:MaxtTotal=400,DefaultMaxPerRoute=200,而服务只连接到https://g.cn时,到这个主机的并发最多只有200;而不是400;而我连接到https://baidu.com 和 https://g.cn时,到每个主机的并发最多只有200;即加起来是400(但不能超过400)
- 而DefaultMaxPerRoute与MaxPerRoute的区别是:前者是所有路由的默认值,后者是可以单独为特定的路由进行配置。
SocketConfig
package org.apache.http.config; /** * Socket configuration. * * @since 4.3 */ @Contract(threading = ThreadingBehavior.IMMUTABLE) public class SocketConfig implements Cloneable { public static final SocketConfig DEFAULT = new Builder().build(); private final int soTimeout; private final boolean soReuseAddress; private final int soLinger; private final boolean soKeepAlive; private final boolean tcpNoDelay; private final int sndBufSize; private final int rcvBufSize; private final int backlogSize; }
RequestConfig
针对请求的配置,查看源码可以看到主要在这个接口中。
package org.apache.http.client.config; /** * Immutable class encapsulating request configuration items. * The default setting for stale connection checking changed * to false, and the feature was deprecated starting with version 4.4. */ @Contract(threading = ThreadingBehavior.IMMUTABLE) public class RequestConfig implements Cloneable { public static final RequestConfig DEFAULT = new Builder().build(); private final boolean expectContinueEnabled; private final HttpHost proxy; private final InetAddress localAddress; private final boolean staleConnectionCheckEnabled; private final String cookieSpec; private final boolean redirectsEnabled; private final boolean relativeRedirectsAllowed; private final boolean circularRedirectsAllowed; private final int maxRedirects; private final boolean authenticationEnabled; private final Collection<String> targetPreferredAuthSchemes; private final Collection<String> proxyPreferredAuthSchemes; private final int connectionRequestTimeout; private final int connectTimeout; private final int socketTimeout; private final boolean contentCompressionEnabled; }
配置项
优化建议
前面介绍的配置项并不是都会用到,常用的配置有如下几个:
- MaxTotal——最大连接数
- DefaultMaxPerRoute——每个路由的默认最大连接数
- connectionRequestTimeout——连接池获取链接超时时间
- connectTimeout——建立连接的超时时间
- socketTimeout——Socket的读超时时间
在Spring中的配置方式
@Configuration public class RestTemplateConfig { @Bean public HttpClientConnectionManager poolingConnectionManager() { PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(); poolingConnectionManager.setMaxTotal(1000); // 连接池最大连接数 poolingConnectionManager.setDefaultMaxPerRoute(500); // 每个主机的并发 return poolingConnectionManager; } @Bean public HttpClientBuilder httpClientBuilder() { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); //设置HTTP连接管理器 httpClientBuilder.setConnectionManager(poolingConnectionManager()); return httpClientBuilder; } @Bean("restTemplate") @LoadBalanced public RestTemplate restTemplate(){ HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpRequestFactory.setHttpClient(httpClientBuilder().build()); httpRequestFactory.setConnectionRequestTimeout(3000);//获取链接超时时间 httpRequestFactory.setConnectTimeout(3000);//指客户端和服务器建立连接的timeout httpRequestFactory.setReadTimeout(120000);//读取数据的超时时间 RestTemplate restTemplate=new RestTemplate(httpRequestFactory); return restTemplate; }
MaxTotal和DefaultMaxPerRoute
这两个是一组相关配置,影响服务器并发量。 在需要提高并发量时大家经常会调大MaxTotal,而忽略了DefaultMaxPerRoute,这样的结果会导致并发量并不会提高。 所以在提高MaxTotal参数时,需要考虑系统架构的主机数,相应的提高DefaultMaxPerRoute。一般的建议是DefaultMaxPerRoute大概是MaxTotal的一半左右。
超时时间设置
其他三个设置主要是针对超时时间的设置。 connectionRequestTimeout和connectTimeout不建议设置过长,在网络情况差的情况下会导致大量的连接数被占用 socketTimeout需要更加服务的具体情况来设置,设置过长会导致连接被占用,设置过短会导致大数据下载时出现超时。 公共接口服务,socketTimeout不宜设置过长,应优化接口设计,不要一次返回大量数据。 文件服务,存在大量文件下载需求,socketTimeout可以根据网络情况适当设置大一点。
总结
最终的设置的调优还是一个持续的过程,需要在服务发布过程中持续的监控进行调优。根据具体的业务情况进行最优的配置。