当前位置: 首页 > 知识库问答 >
问题:

HttpClient连接池关闭

司空和悌
2023-03-14

我正在使用HttpClient v4.5.5

我有一个HttpClient如下:

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
    connManager.setMaxTotal(totalMaxConnections);
    connManager.setDefaultMaxPerRoute(defaultMaxConnPerRoute);
CloseableHttpClient httpClient =HttpClients.custom().setConnectionManager(connManager).setConnectionManagerShared(true).build();

然后我使用超文本传输协议客户端如下:

protected Response connect(final Function<AbstractHttpAdapter, CloseableHttpResponse> pcAction) {
    Response response = null;
    final Instant begin = Instant.now();
    try {
        final CloseableHttpResponse closableResp = pcAction.apply(this);
        try {
            final Instant end = Instant.now();
            if (closableResp != null) {
                final HttpEntity responseEntity = closableResp.getEntity();
                if (responseEntity != null) {
                    response = new Response();
                    InputStream is = responseEntity.getContent();
                    try {

                        final ContentType contentType = ContentType.getOrDefault(responseEntity);
                        Charset charset = contentType.getCharset();
                        if (charset == null)
                            charset = Charset.forName("UTF-8");
                        response.responseText = IOUtils.toString(is, charset.toString());
                        if (closableResp.getStatusLine() != null) {
                            response.statusLine = closableResp.getStatusLine();

                        }
                        Map<String, String> responseHeaders = new HashMap<>();
                        Header[] headers = closableResp.getAllHeaders();
                        for (Header h : headers) {
                            responseHeaders.put(h.getName(), h.getValue());
                        }
                        response.responseHeaders = responseHeaders;
                        response.responseDuration = Duration.between(begin, end).toMillis();
                    } catch (UnsupportedOperationException | IOException e) {
                        LOGGER.error("IO Error: [{}]", e.getMessage());
                        LOGGER.debug("IO Error: {}", e);
                        return null;
                    } finally {
                        is.close();
                    }
                }
            } else {
                LOGGER.debug("NULL CloseableHttpResponse!");
            }
        } finally {
            if (closableResp != null)
                closableResp.close();
        }
    } catch (IOException e) {
        LOGGER.error("IO Error: [{}]", e.getMessage());
        LOGGER.debug("IO Error: {}", e);
        response = null;
    } catch (Exception ex) {
        LOGGER.error("IO Error: [{}]", ex.getMessage());
        LOGGER.debug("IO Error: {}", ex);
        response = null;
    }
    return response;
}

public CloseableHttpResponse executePost(final URL url, final String request, final int connectTimeout,
        final int readTimeout, Map<String, String> extraHeaders) {

    LOGGER.trace("Executing post request...");
    CloseableHttpResponse closeableHttpResponse = null;
    final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
    final RequestConfig requestConfig = requestConfigBuilder.setSocketTimeout(readTimeout)
            .setConnectTimeout(connectTimeout).build();

    final URI uri = prepareUri(url, null);
    final HttpPost httpPost = new HttpPost(uri);
    try {
        httpPost.setEntity(new StringEntity(request, StandardCharsets.UTF_8));
        httpPost.setConfig(requestConfig);
        if (MapUtils.isNotEmpty(extraHeaders)) {
            for (Map.Entry<String, String> header : extraHeaders.entrySet()) {
                httpPost.setHeader(header.getKey(), header.getValue());
            }
        }
        closeableHttpResponse = httpClient.execute(httpPost, HttpClientContext.create());
    } catch (ClientProtocolException e) {
        LOGGER.error("HTTP Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    } catch (IOException e) {
        LOGGER.error("IO Error for URL [{}] and RequestParams [{}]: {}", url, request, e.getMessage());
        LOGGER.debug("IO Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    } catch (Exception e) {
        LOGGER.error("General Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    }
    return closeableHttpResponse;
}

通过threadPoolTaskScheduler定期调用连接(每隔几分钟)

偶尔我会出错

java.lang.IllegalStateException:连接池关闭,据我所知,这种情况要么发生在旧的HttpClient版本上,要么发生在您关闭HttpClient时。我没有这样做。所以我不明白为什么会出现这个错误。它会恢复,但有这样的异常是个问题。

共有1个答案

魏誉
2023-03-14

得到了相同的错误,但最终解决了。这个错误导致我使用try(){},如下所示:

try (PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager()) {
                manager.setMaxTotal(600);
                manager.setDefaultMaxPerRoute(100);

这一建设将自动关闭资源。

类:PoolighttpClientConnectionManager存在如下方法:

 public void close() {
        this.shutdown();
    }

最后将调用close()。

 类似资料:
  • 版本 上下文 我只是想在核心示例io中运行http客户端。维特斯。实例果心http。易于理解的客户运行此示例时,its发现已建立的连接在请求完成后未关闭。 服务器端我没有看到任何问题。因为在尝试使用jmeter和服务器时,它工作得很好。所以我认为问题在于HttpClient。 有人能帮我吗? 提前谢谢。复制的步骤 额外的 即使在请求和响应结束后,仍会显示以下内容。在给LINUX 窗户 在LINUX

  • 问题内容: 如何使用HttpClient创建连接池? 我必须经常连接同一台服务器。值得建立这样一个游泳池吗? 是否可以保持实时连接并将其用于各种请求,如果可以,我该如何做? 我正在使用Apache HTTP Client在Java中进行开发。 问题答案: [假设Java和Apache的HttpClient] 使用ThreadSafeClientConnManager。将单个全局实例传递给每个Htt

  • 当我使用CloseableHttpClient和do Execute方法时,它在第一次正常工作,但之后从未成功。它将引发表示“连接池关闭”的异常 有人说是因为我还没有关闭客户端有人说是httpClient 4.3中的bug 我的项目不存在上述问题,但仍然无法正常工作

  • 我正在Java中运行Apache HTTP POST请求,每当我超过1300个请求时,就会出现以下错误,我需要发出更多的请求,大约40k,我可以做些什么来纠正相同的错误?

  • 我们正在使用持久连接,并尝试在x时间段后强制断开连接。虽然我认为我们在理论上可以使用连接保持投资策略,但我能说的是,这只适用于回应之后。。i、 e.当连接空闲时。 我们的问题是... 假设有一台客户端,通过负载平衡器访问两台服务器(A、B)。当其中一台服务器脱机(B)时,所有新连接都会在服务器(A)上建立。现在,当另一台服务器(B)重新联机时,它将保持空闲状态,因为所有连接都在另一台服务器(A)上

  • 我有一个带有数据库连接池的grails/groovy web应用程序。设置如下所示: 我使用java melody进行诊断和监控,并注意到一些奇怪的行为。例如,当执行查询数据库的作业时,连接可以超越maxActive属性。为什么这是可能的? 我需要显式关闭Grails连接吗?该作业调用一个服务方法,该方法通过withCriteria Grails调用简单地执行DB查询,如: 似乎每次运行这个程序,