[背景]
应用中线程数量 一直在增加,dump线程日志发现大量IdleConnectionEvictor日志。
源码分析:
//evictExpiredConnections 这个配置作用:
//设置一个定时线程,定时清理闲置连接,可以将这个定时时间设置为 keep alive timeout 时间的一半以保证超时前回收
//所以在build httpclinet 的时候可以设置evictExpiredConnections()
if (evictExpiredConnections || evictIdleConnections) {
//这里要看IdleConnectionEvictor源码,里面会创建一个线程
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm,
maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit != null ? maxIdleTimeUnit : ,
maxIdleTime, maxIdleTimeUnit);
(new Closeable() {
@Override
public void close() throws IOException {
();
try {
(1L, );
} catch (final InterruptedException interrupted) {
().interrupt();
}
}
});
();//这里会创建evaictor线程
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
所以每创建一个httpclient就会创建一个evictor线程,如果不设置连接超时时间和空闲线程回收的话这些线程会一直存在;
解决方法:
创建httpClient连接池,自定义connectManager
public class HttpClientFactory {
private CloseableHttpClient httpClient;
public void construct(){
RequestConfig config = ()
.setSocketTimeout(10000)//请求获取数据的超时时间(即响应时间),单位毫秒
.setConnectTimeout(10000)//设置连接超时时间,单位毫秒
.setConnectionRequestTimeout(500)//设置从connect Manager(连接池)获取Connection 超时时间,单位毫秒
.build();
//设置连接存活时间,总的最大连接数和每个路由的最大连接数
PoolingHttpClientConnectionManager poolHttpConnManager = new PoolingHttpClientConnectionManager(60, );
(60);
(20);
//初始化client
HttpClientBuilder httpBuilder = ()
.setKeepAliveStrategy()
.setDefaultRequestConfig(config)
.setConnectionManager(poolHttpConnManager)
.evictExpiredConnections()
//MaxIdleTime 必须小于服务端的关闭时间否则有可能出现NoHttpResponse
.evictIdleConnections(5,);//用来关闭闲置连接,它会启动一个守护线程进行清理工作。用户可以通过builder#evictIdleConnections开启该组件,并通过builder#setmaxIdleTime设置最大空闲时间。
httpClient=();
}
public void destroy() throws Exception{
if(null != ){
();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34