gpt4 book ai didi

java - Apache HttpClient 抛出 java.net.SocketException : Connection reset if I use it as singletone

转载 作者:行者123 更新时间:2023-12-02 18:25:55 24 4
gpt4 key购买 nike

我创建了一个 Apache HTTP 客户端

             CloseableHttpClient client = HttpClients.custom()
.setMaxConnPerRoute(25)
.setMaxConnTotal(50)
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectionRequestTimeout(20_000)
.build())
.build();

我将其用作单例。我有这种发送请求的方法:

public RestResponse sendPost(String serverUrl, String body) throws RestException {
try {
HttpPost httpPost = new HttpPost(serverUrl);
httpPost.setEntity(new StringEntity(body));

try (CloseableHttpResponse response = client.execute(httpPost)) {
RestResponse restResponse = new RestResponse();
restResponse.setCode(response.getStatusLine().getStatusCode());
restResponse.setBody(EntityUtils.toString(response.getEntity()));
return restResponse;
}
} catch (Exception e) {
throw new RestException(e);
}
}

它工作正常。但是在闲置一段时间(5-6 分钟)后,如果我发送请求,我会收到 "java.net.SocketException: Connection reset"

我有两个问题

  1. 如何找到这个时间开始的地方?这些参数对我不起作用

                 .setSocketTimeout(25_000)
    .setConnectTimeout(26_000)
  2. 解决此问题的最佳方法是什么? (我的意思是在每次请求之后或之前重试请求或更改超时或重新连接)

最佳答案

这是经典(阻塞)i/o 的一般限制:阻塞连接在空闲时无法对任何 i/o 事件使用react(未参与 i/o 操作)。同样,超时设置对空闲连接没有影响。

可以采用多种防御措施来最大程度地减少持久连接重置的可能性:

  1. 在一段时间不活动后(例如,1 秒后)从连接池租用时验证持久连接
    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build();
  1. 主动从连接池中驱逐过期连接和空闲超过一定时间(例如5s)的连接
    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.evictExpiredConnections()
.evictIdleConnections(5L, TimeUnit.SECONDS)
.build();
  1. 如果一切都失败了,重试可以安全重试的请求。当需要更多控制时,人们可能希望使用自定义 HttpRequestRetryHandler 实现而不是默认实现。
    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.setRetryHandler(DefaultHttpRequestRetryHandler.INSTANCE)
.build();
  1. 当预计长时间不活动时,手动从池中逐出连接。这是 HttpClient 在使用 evictIdleConnections 方法配置时自动为您执行的操作,代价是额外的监视器线程。
    cm.closeIdleConnections(0, TimeUnit.MICROSECONDS);

关于java - Apache HttpClient 抛出 java.net.SocketException : Connection reset if I use it as singletone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70175836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com