CONNECTION_RESET(HttpClient Connection Reset异常)
1.背景
最近项目使用HttpClient 进行服务调用,为了提高利用率,使用了HttpClient 连接池并进行了链接参数调优;
链接池:
PoolingHttpClientConnectionManager
参数:
ConnectTimeout=
3000;链接建立的超时时间
SocketTimeout=10000;
响应超时时间,超过此时间不再读取响应;
ConnectionRequestTimeout= 3000; http clilent中从connetcion pool中获得一个connection的超时时间;
MaxPerRoute = 200
MaxTotal = 400
注意这里有个坑,连接池默认MaxTotal =2,最大仅支持两个并发;
2.问题
在调整了上述配置之后,发现偶尔出现Connection Reset的异常情况
3.分析过程
出现Connection Reset的原因
1.客户端在读取数据,服务端不再发送新数据(服务器主动关闭了数据)
解决:加入驱逐配置时间
evictIdleConnections(40, TimeUnit.SECONDS)
httpClient
= HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setConnectionRequestTimeout(TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(TIMEOUT).build()).setConnectionManager(cm).evictIdleConnections(IDEL_TIMEOUT, TimeUnit.SECONDS).build()
;
4.带来的问题
上述配置完成后,发现运行一段时间后内存资源不足,导致服务雪崩
其实这里主要也是引入httpclient池和evictIdleConnections配置造成的,看源码
每次会new一个守护线程,这里就是造成线程资源不足的主要原因;
解决方案:
这里其实应该把
httpClient 作为单例模式来处理
private
static
CloseableHttpClient httpClient;
@
PostConstructpublic void init()
{ PoolingHttpClientConnectionManager cm = ne
w P
oolingHttpClientConnectionManager(); if
(!
autoRefreshConfigBean.getMaxTotal().equ
als(cm
.getMaxTotal()) || !autoRefreshConfigBean.getDefaultMaxPerRoute().equ
als(cm
.getDefaultMaxPerRoute())) { cm.setMaxTotal(autoRefreshConfigBean.getMaxTotal()); // 将每
个路由基础的连接增加
cm.setDefaultMaxPerRoute(autoRefreshConfigBean.getDefaultMaxPerRoute()); } httpClient = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setConnectionRequestTimeout(TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(TIMEOUT).build()).setConnectionManager(cm).evictIdleConnections(IDEL_TIMEOUT, TimeUnit.SECONDS).build(); log.info(“========
=====PoolingHttpClientConnectionManager-CloseableHttpClient被初始化=============”);}
版权声明:本文内容由网友提供,该文观点仅代表作者本人。本站(http://www.zengtui.com/)仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 3933150@qq.com 举报,一经查实,本站将立刻删除。