快乐赚

手机浏览器connectionreset101怎么解决(HttpClient Connection Reset异常)

 人阅读 | 作者舞动奇迹 | 时间:2023-08-29 15:31

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;
@PostConstruct
public void init() 
    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被初始化=============");
}

文章标签:

本文链接:『转载请注明出处』