web-dev-qa-db-fra.com

exception httpclient "org.Apache.http.conn.ConnectionPoolTimeoutException: délai d'attente pour la connexion"

J'essaye d'envoyer la demande à mon serveur, avec le code suivant. il a toujours échoué à la 3ème demande.

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

l'exception comme suit:

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)
28
user1447011

J'ai eu le même problème et j'ai trouvé le correctif… .. Ce délai est dû à une fuite de connexion. Dans mon cas, j'utilise la méthode httpDelete et ne consomme pas la réponse. Au lieu de cela, vérifier le statut de la réponse. 

Le correctif est, l'entité de réponse doit être consommée. Afin de garantir la libération appropriée des ressources système, il est nécessaire de fermer le flux de contenu associé à l'entité.

J'ai donc utilisé EntityUtils.consumeQuietly(response.getEntity()); qui garantit que le contenu de l'entité est entièrement consommé et que le flux de contenu, s'il existe, est fermé.

47

Je l'ai réparé! ajoutez mPost.releaseConnection() dans les blocs finally.

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

DO mettre à jour le paquet org.Apache.httpcomponents à 4.2.1

25
user1447011

Mettez simplement la ligne où vous obtenez votre réponse dans try-with-resources et utilisez CloseableHttpResponse au lieu de HttpResponse comme ceci:

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

L'objet mHttpResponse sera automatiquement consommé et fermé pour vous

J'espère que cela t'aides!

2
Suyog Tilak

Cela peut également arriver si vous utilisez ApacheHttpClient avec DropWizard 0.6.2, ce qui crée en arrière-plan une MultiThreadedHttpConnectionManager avec une configuration par défaut - et cette configuration par défaut n'autorisait que 2 connexions http simultanées plus d'infos ici .

Donc, avec cette configuration, si votre serveur est submergé et fait des demandes au même hôte tout le temps, vous aurez un maximum de 2 connexions autorisées à la fois!

2
Brad Parks

Comme Rama a dit, cela pourrait être le signe d'une fuite de connexion. 

releaseConnection() pourrait aider à résoudre ce problème, mais vous devrez peut-être en déterminer la cause.

En outre, cela peut se produire car il n'y a pas de connexion disponible que vous pouvez louer, ce qui pourrait arriver si vous n'avez pas timeout config pour la HttpClient. Dans ce cas, releaseConnection() n'aiderait pas.

0
Sanghyun Lee