HttpClient连接池关闭

时间:2018-02-08 12:42:25

标签: java apache-httpclient-4.x apache-httpcomponents

我使用的是HttpClient v4.5.5

我有HttpClient如下:

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

然后我使用http客户端如下:

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;
}

定期(每隔几分钟)通过connect致电threadPoolTaskScheduler

偶尔会出现错误

java.lang.IllegalStateException: Connection pool shut down从我所看到的情况发生这种情况发生在较旧的HttpClient版本或关闭HttpClient时。我不这样做。所以我无法理解为什么会出现这个错误。它恢复了,但这是一个像这样的例外的问题。

1 个答案:

答案 0 :(得分:0)

遇到同样的错误,但终于解决了。 此错误导致我如下使用try(){}:

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

此构造将自动关闭资源。

class:PoolingHttpClientConnectionManager存在如下方法:

//hangfire
services.AddHangfire(x => x.UseSqlServerStorage(connectionString));
services.AddDbContext<OmniServiceDbContext>(options => 
        options.UseSqlServer(Configuration.GetSection("ConnectionStrings:ConnectionString").Value), ServiceLifetime.Transient);

services.AddTransient(typeof(IPostedDataService), typeof(PostedDataService));
services.AddSingleton<IConfiguration>(Configuration);

最后将调用close()。