HttpClient pend sur socketRead0 avec une méthode exécutée avec succès

dans notre application web, un utilisateur peut soumettre une url. Nous allons récupérer les données et analyser le côté serveur. Pour chaque requête, nous utilisons un HttpClient avec les paramètres (pertinents) suivants:

connectionManager.getParams().setConnectionTimeout(10000);
connectionManager.getParams().setSoTimeout(10000);

quand J'appelle HttpMethod.le code d'État a déjà été vérifié pour être acceptable. À ce point le fil est suspendu avec cette trace de pile:

java.net.SocketInputStream.socketRead0 ( native code )
java.net.SocketInputStream.read ( SocketInputStream.java:150 )
java.net.SocketInputStream.read ( SocketInputStream.java:121 )
java.io.BufferedInputStream.read1 ( BufferedInputStream.java:273 )
java.io.BufferedInputStream.read ( BufferedInputStream.java:334 )
java.io.FilterInputStream.read ( FilterInputStream.java:133 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:108 )
java.io.FilterInputStream.read ( FilterInputStream.java:107 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:127 )
org.apache.commons.httpclient.HttpMethodBase.getResponseBody ( HttpMethodBase.java:690 )

Je ne peux pas trouver L'URL exacte pour laquelle cela s'est produit (était un incident sur un environnement réel) et j'ai été incapable de le reproduire. J'aimerais penser qu'il s'agit simplement du serveur auquel nous nous connectons et qui se comporte étrangement, mais peut-être que je manque quelque chose. Dans les deux cas, y a-t-il un moyen pour moi d'empêcher l'appel de la méthode de blocage d'attendre éternellement? Le SoTimeout est aussi le socket read timeout? Y a-t-il un autre décor qui me manque?

5
demandé sur Kafkaesque 2013-04-08 12:45:24

5 réponses

j'ai toutes les configurations de timeouts très bien mais j'ai découvert que nous avons sur l'url qui fait le chunking http mais n'envoie aucun résultat(fonctionne très bien dans chrome, mais dans le client http il reste à jamais même avec le timeout). Heureusement, je possède le serveur et juste retourner quelques ordures et il ne pend plus. Cela ressemble à un bug très unique dans le fait que le client http ne gère pas bien une sorte de cas vide de chunking(bien que je puisse être loin)....Je sais juste qu'il est accroché à chaque fois sur cette même url avec des données vides et cette url est http chunking csv télécharger à nouveau à notre client http.

3
répondu Dean Hiller 2013-10-04 19:13:17

quand J'appelle HttpMethod.le code d'État a déjà été vérifié pour être acceptable. À ce point le fil pend

on dirait que vous avez un problème avec la synchronisation des appels ... vous devez vous assurer que la méthode

HttpMethod.get respondebody

est appelé séquentiellement ou devrait utiliser un mutex (sémaphore ) pour la partie qui change le code d'état

vous devez également diminuer votre limite de temps pour prévenir les pendaisons.

0
répondu Stephan 2013-04-08 08:59:28

nous voyons cela de manière cohérente dans notre implémentation et il semble que le client http ne gère pas correctement les mauvais serveurs ou quelque chose et qu'il ne chronomètre pas.....Je peux me reproduire dans notre environnement avec ce projet de base de données open source et la trace de la pile est un peu différente...

SocketInputStream.socketRead0 (FileDescriptor, byte[], int, int, int) ligne: non disponible [méthode native]

SocketInputStream.lire (octet[], int, int) ligne: 129

SocketInputBuffer (AbstractSessionInputBuffer).fillBuffer () line: 166

SocketInputBuffer.ligne fillBuffer (): 90 SocketInputBuffer (AbstractSessionInputBuffer).ligne readLine (CharArrayBuffer): 281

DefaultHttpResponseParser.parseHead (SessionInputBuffer) ligne: 92

DefaultHttpResponseParser.parseHead (SessionInputBuffer) ligne: 62

DefaultHttpResponseParser (AbstractMessageParser).parse() de la ligne: 254

DefaultClientConnection (Abstractthttpclientconnection).receiveResponseHeader () ligne: 289 DefaultClientConnection.receiveResponseHeader () line: 252

BasicPooledConnAdapter (AbstractClientConnAdapter).receiveResponseHeader () ligne: 219 HttpRequestExecutor.doReceiveResponse (HttpRequest, HttpClientConnection, HttpContext) ligne: 300 HttpRequestExecutor.exécuter (HttpRequest, HttpClientConnection, HttpContext) line: 127

DefaultRequestDirector.ligne tryExecute(RoutedRequest, HttpContext): 712 DefaultRequestDirector.exécution (HttpHost, HttpRequest, HttpContext) ligne: 517

DefaultHttpClient (AbstractHttpClient).exécution de la ligne (HttpHost, HttpRequest, HttpContext): 906 DefaultHttpClient (AbstractHttpClient).exécution (HttpUriRequest, HttpContext) ligne: 805

ReadAggregations.processAggregation(String, Compteur, compteur, compteur, Compteur) en ligne: 153

ReadAggregations.start() de la ligne: 96

ReadAggregations.ligne principale (String []): 70

0
répondu Dean Hiller 2013-10-04 18:54:06

vous pouvez essayer d'annuler la requête avec HttpUriRequest#abort (), voir https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html#abort%28%29 . Cependant, mettre un timemout qui ne nécessite aucune interception serait plus agréable. Voici une question connexe: fixer le temps dans le client http apache

0
répondu static-max 2017-05-23 11:46:41

HttpClient distingue entre connexion et requête. setSoTimeout va configurer le délai d'expiration du socket de connexion tandis que setConnectionTimeout va configurer à la fois le délai d'expiration pour le gestionnaire de connexion (combien de temps pour attendre une connexion) et pour l'établissement de la connexion elle-même. Dans le code que vous avez fourni, vous ne définissez pas de délai pour la socket utilisée pour la requête elle-même, et malheureusement, HttpClient n'a pas de délai par défaut pour cela.

comment je fais en v4.4.1:

// Configure the socket timeout for the connection, incl. ssl tunneling
connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(200);
connManager.setDefaultMaxPerRoute(100);

SocketConfig sc = SocketConfig.custom()
    .setSoTimeout(soTimeoutMs)
    .build();

connManager.setDefaultSocketConfig(sc);

HttpClient client = HttpClients.custom()
            .setConnectionManager(connManager)
            .setConnectionManagerShared(true)
            .build();

// configure the timeouts (socket and connection) for the request
RequestConfig.Builder config = = RequestConfig.copy(RequestConfig.DEFAULT);
config.setConnectionRequestTimeout(connectionTimeoutMs);
config.setSocketTimeout(socketTimeoutMs);

HttpRequestBase req = new HttpGet(uri);
req.setConfig(config.build());

client.execute(req);
0
répondu GaspardP 2016-01-04 18:59:46