简体   繁体   English

httpclient 异常“org.apache.http.conn.ConnectionPoolTimeoutException:等待连接超时”

[英]httpclient exception “org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection”

I am trying to send request to my server, with following code.我正在尝试使用以下代码向我的服务器发送请求。 it failed at 3rd request, always.它总是在第三次请求时失败。

import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

public class HttpClientTest {
    private HttpClient client;

    public HttpClientTest() {
        HttpParams params = new BasicHttpParams();
        params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000);  
        params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000);

        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "utf-8");
        HttpProtocolParams.setUseExpectContinue(params, true);
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();
        cm.setMaxTotal(100);
        client = new DefaultHttpClient(cm, params);

        while (true) {
            HttpPost mPost = new HttpPost("http://myip/myservice");

            JSONObject json = new JSONObject();
            try {
                json.put("serialNumber", "abcd");
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
            StringEntity s = null;
            try {
                s = new StringEntity(json.toString());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }               
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            mPost.setEntity(s);

            JSONObject response = null;

            System.out.println("HttpClientTest ---> send post");
            HttpResponse mHttpResponse;
            try {
                mHttpResponse = client.execute(mPost);
                System.out.println("HttpClientTest  ---> get response");
                if(mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    HttpEntity entity = mHttpResponse.getEntity(); 
                    ContentType contentType = ContentType.getOrDefault(entity);
                    Charset charset = contentType.getCharset();
                    response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(), charset)));

                    System.out.println("HttpClientTest ---> get result:" + response.toString());
                } else {
                    mPost.abort();
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        HttpClientTest t = new HttpClientTest();
    }
}

the exception as following:异常如下:

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:417)
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:300)
    at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:224)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
    at com.i360r.client.takeaway.network.HttpClientTest.<init>(HttpClientTest.java:68)
    at com.i360r.client.takeaway.network.HttpClientTest.main(HttpClientTest.java:88)

I had the same problem and I found the fix.我遇到了同样的问题,我找到了解决方法。 This timeout is because of a connection leak.此超时是因为连接泄漏。 In my case, I'm using httpDelete method and not consuming the response.就我而言,我使用的是httpDelete方法并且不消耗响应。 Instead, I'm checking the status of the response.相反,我正在检查响应的状态。

The fix is, the response entity needs to be consumed.解决方法是,需要使用响应实体。 In order to ensure the proper release of system resources, one must close the content stream associated with the entity.为了保证系统资源的正确释放,必须关闭与实体关联的内容流。

So I used EntityUtils.consumeQuietly(response.getEntity());所以我使用了EntityUtils.consumeQuietly(response.getEntity()); which ensures that the entity content is fully consumed and the content stream, if exists, is closed.这确保实体内容被完全消耗,并且内容流(如果存在)被关闭。

I have fixed it!我已经修好了! add mPost.releaseConnection() in finally blocks.finally块中添加mPost.releaseConnection()

 try {
 } catch (Exception e) {
 } finally {
  mPost.releaseConnection();
 }

DO update package org.apache.httpcomponents to 4.2.1更新包org.apache.httpcomponents到 4.2.1

Just put the line where you are getting your response inside try-with-resources and use CloseableHttpResponse instead of HttpResponse like this:只需将在 try-with-resources 中获取响应的行放在 try-with-resources 中,然后使用 CloseableHttpResponse 而不是 HttpResponse ,如下所示:

try(final CloseableHttpResponse mHttpResponse = client.execute(mPost);)
{
 System.out.println("HttpClientTest  ---> get response");
 ....remainder code

The mHttpResponse object will be auto consumed and closed for you mHttpResponse 对象将自动为您使用和关闭

Hope this helps!希望这可以帮助!

Use a CloseableHttpClient instead of HttpClient .使用CloseableHttpClient而不是HttpClient You'll get a CloseableHttpResponse instead of a HttpResponse which support close() .您将获得CloseableHttpResponse而不是支持close()HttpResponse So, when you are done with the response, just close it, no need to close the connection.因此,当您完成响应时,只需关闭它即可,无需关闭连接。

CloseableHttpResponse response = closableHttpClient.execute(httpPost, context);

...do what you need to do with it: ...做你需要做的事情:

response.close();

This can also happen if you're using ApacheHttpClient with DropWizard 0.6.2, which behind the scenes creates an MultiThreadedHttpConnectionManager with a default configuration - and that default configuration only allowed 2 concurrent http connections at a time more info here .如果您将ApacheHttpClient与 DropWizard 0.6.2 一起使用,也会发生这种情况,它在后台创建了一个带有默认配置的MultiThreadedHttpConnectionManager - 该默认配置一次只允许 2 个并发 http 连接, 更多信息请点击此处

So with this configuration, if your server is getting swamped and making requests to the same host all the time, you'll have max 2 connections allowed running at a time!因此,使用此配置,如果您的服务器被淹没并一直向同一主机发出请求,则一次最多允许运行 2 个连接!

We faced the same issue, and we were limited because the connection from pool has initial value of DefaultMaxPerRoute as 2. Ours was an API which would fire different calls with same URI but, different body.我们遇到了同样的问题,我们受到限制,因为来自池的连接的 DefaultMaxPerRoute 的初始值为 2。我们是一个 API,它会使用相同的 URI 触发不同的调用,但主体不同。 Once we set it explicitly to higher value like this一旦我们像这样明确地将它设置为更高的值

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(40);
    cm.setDefaultMaxPerRoute(20);

we were able to resolve it.我们能够解决它。

We were hitting this error when writing and reading parquets via spark.我们在通过 spark 写入和读取镶木地板时遇到了这个错误。 The exact error was:确切的错误是:
com.amazonaws.SdkClientException: Unable to execute HTTP request: Timeout waiting for connection from pool com.amazonaws.SdkClientException:无法执行 HTTP 请求:等待池中的连接超时

We finally figured out that this was related to the upgrade of Hadoop to version 3.1.3终于搞清楚这和Hadoop升级到3.1.3版本有关

Seems that in this new version the Hadoop, the property name been changed from:似乎在这个新版本的 Hadoop 中,属性名称从:
fs.s3a.connection.maximum fs.s3a.connection.maximum
to:到:
spark.hadoop.fs.s3a.connection.maximum spark.hadoop.fs.s3a.connection.maximum

Renaming the property in our spark configuration, set us back on track.在我们的 spark 配置中重命名属性,让我们回到正轨。

I hit the same error.我遇到了同样的错误。 It turns out that I needed to close the response.事实证明,我需要关闭响应。

CloseableHttpResponse response = null;
try {
       response = ##some code
} catch(Exception e) {
  if (response != null) {
      response.close();
  }
}

As Rama said, this could be a sign of a connection leak.正如Rama所说,这可能是连接泄漏的迹象。

releaseConnection() could help resolve this issue but you might need to find out the root cause. releaseConnection()可以帮助解决此问题,但您可能需要找出根本原因。

Also, this could happen because there's no available connection you can lease which could happen when you don't have timeout config for the HttpClient .此外,这可能是因为没有您可以租用的可用连接,当您没有HttpClient timeout配置时可能会发生这种情况。 In this case, releaseConnection() wouldn't help.在这种情况下, releaseConnection()无济于事。

In my case the bufferedReader that was consuming the entity content stream was not being closed.在我的情况下,使用实体内容流的 bufferedReader 没有被关闭。 Closing it resolved the error.关闭它解决了错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RestTemplate + ConnectionPoolTimeoutException:等待来自池的连接超时 - RestTemplate + ConnectionPoolTimeoutException: Timeout waiting for connection from pool 错误:请求中的异常:org.apache.http.conn.HttpHostConnectException:与http:// ********:80的连接被拒绝 - ERROR:Exception in request: org.apache.http.conn.HttpHostConnectException: Connection to http://********:80 refused Websphere httpclient NoSuchMethodError org.apache.http.conn.Scheme - Websphere httpclient NoSuchMethodError org.apache.http.conn.Scheme 是否可以窥视HttpClient的org.apache.http.conn.EofSensorInputStream? - Is it possible to peek HttpClient's org.apache.http.conn.EofSensorInputStream? 线程“ main” org.apache.http.conn.HttpHostConnectException中的异常:连接到//失败:连接超时:connect - Exception in thread “main” org.apache.http.conn.HttpHostConnectException: Connect to // failed: Connection timed out: connect 连接 org.apache.http.conn.HttpHostConnect 时出现超时错误 - Timeout error while connecting org.apache.http.conn.HttpHostConnect org.apache.http.conn.HttpHostConnectException:拒绝连接到http:// localhost - org.apache.http.conn.HttpHostConnectException: Connection to http://localhost refused Apache HttpClient in Java, instream.toString = org.apache.http.conn.EofSensorInputStream - Apache HttpClient in Java, instream.toString = org.apache.http.conn.EofSensorInputStream HTTPClient“主要” java.lang.NoSuchFieldError:实例位于org.apache.http.conn.ssl.SSLConnectionSocketFactory。 <clinit> - HTTPClient “main” java.lang.NoSuchFieldError: INSTANCE at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit> 如何关闭 org.apache.http.client.HttpClient 对象的连接 - How to close connection of org.apache.http.client.HttpClient object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM