utils org httpclientbuilder ejemplo commons java apache-commons-httpclient

java - org - HttpClient atascado sin excepción



org apache commons httpclient httpclient jar (7)

Estoy desarrollando una aplicación de larga ejecución que usa mucho el HttpClient de apache.

En mi primera ejecución de prueba, la aplicación funcionó perfectamente hasta que se atascó. No se detuvo, no arrojó ninguna excepción, simplemente permanece allí sin hacer nada.

Hice una segunda carrera justo ahora y detuve el tiempo y se detuvo después de aprox. 24 horas de carrera contante. Además, me di cuenta de que la conexión a Internet de mi computadora portátil en la que estaba funcionando se terminó en el momento exacto en que la aplicación se atascó. Tuve que reiniciar mi adaptador WLAN para que la red volviera a funcionar.

La aplicación, sin embargo, no volvió a funcionar después de que la conexión estaba nuevamente activa. Y ahora, está atascado de nuevo.

¿Hay algún controlador de tiempo de espera que no conozca en el HttpClient? ¿Por qué mi aplicación no lanza una excepción cuando la conexión se interrumpe?

La parte que utiliza el cliente se ve como sigue;

public HttpUtil(ConfigUtil config) { this.config = config; client = new DefaultHttpClient(); client.getParams().setParameter(HttpProtocolParams.USER_AGENT, this.config.getProperty("httputil.userAgent")); } public String getContentAsString(String url) throws ParseException, ClientProtocolException, IOException { return EntityUtils.toString( client.execute( new HttpGet(url)).getEntity()); }

La aplicación llama repetidamente a httputil.getContentAsString() en las URL que necesita.


A partir de la versión 4.4, las respuestas de los usuarios user2393012 y Stephen C han quedado en desuso. No estoy seguro de si hay otra forma de hacerlo, pero la forma en que lo hago es mediante el uso de un paradigma de constructor, HTTPClientBuilder.

Ex.

HttpClients.custom().setConnectionTimeToLive(1, TimeUnit.MINUTES).build()

Un problema muy similar (en realidad podría haber sido el problema de OP) a lo que OP mencionó también ocurre, pero se debe a que Apache establece las conexiones concurrentes predeterminadas a solo dos conexiones por cliente. La solución a esto sería aumentar las conexiones máximas o cerrarlas si es posible.

Para aumentar las conexiones máximas:

HttpClients.custom().setMaxConnPerRoute(100000).build()

Para cerrar conexiones, puede usar un BasicHttpClientConnectionManager y llamar al método close para


De forma predeterminada, HttpClient no se agota (lo que causa más problemas de los que ayuda). Lo que está describiendo podría ser un problema de hardware, si su adaptador de red se apagó, el HttpClient se bloqueará.

Aquí están los parameters establecidos para HttpParams como parte del constructor para DefaultHttpClient incluidos

http.socket.timeout : define el tiempo de espera del socket (SO_TIMEOUT) en milisegundos, que es el tiempo de espera para esperar datos o, dicho de otra manera, un período de inactividad máximo entre dos paquetes de datos consecutivos). Un valor de tiempo de espera de cero se interpreta como un tiempo de espera infinito. Este parámetro espera un valor de tipo java.lang.Integer. Si este parámetro no está establecido, las operaciones de lectura no se desactivarán (tiempo de espera infinito).

Eso establecerá un tiempo de espera en la conexión, por lo que después del tiempo de espera establecido se lanzará una excepción.


Este código ahora está en desuso (obtener HttpParams, etc.). Una mejor manera es:

RequestConfig defaultRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH).setExpectContinueEnabled(true).setStaleConnectionCheckEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build(); HttpGet httpGet = new HttpGet(url); RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig).setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build(); httpGet.setConfig(requestConfig);


No ha dicho qué versión de HttpClient está utilizando, pero suponiendo que es la versión 4, este artículo de blog explica qué hacer.

DefaultHttpClient httpClient = new DefaultHttpClient(); HttpParams params = httpClient.getParams(); HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis); HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);


Tengo todos los ajustes de tiempo de espera bien, pero descubrí que tenemos un url que hace http chunking pero no envía resultados (funciona bien en Chrome, pero en el cliente http se cuelga para siempre incluso con el tiempo de espera establecido). Por suerte soy dueño del servidor y solo devuelvo un poco de basura y ya no se cuelga. Esto parece ser un error muy particular en que el cliente http no maneja bien algún tipo de caso de fragmentación vacía (aunque podría estar muy lejos) ... Solo sé que se cuelga cada vez en esa misma URL con datos vacíos y esa URL es http chunking csv descargar de nuevo a nuestro cliente http.


Tuve el mismo problema, se atascó porque no cerré DefaultHttpClient.
Así que esto está mal:

try{ DefaultHttpClient httpclient = new DefaultHttpClient(); ... } catch (Exception e){ e.PrintStackTrace(); }

Y esto es correcto:

try (DefaultHttpClient httpclient = new DefaultHttpClient()){ ... } catch (Exception e){ e.PrintStackTrace(); }

Espero que ayude a alguien.


Di una respuesta similar en otro hilo ( HttpClient se cuelga en socketRead0 con un método ejecutado con éxito )

En mi caso, estaba configurando connectionTimeout y socketTimeout en la solicitud, pero no en el socket de conexión utilizado durante el establecimiento de la conexión SSL. Como resultado, alguna vez colgaría durante el protocolo SSL. A continuación se muestra un código que establece los 3 tiempos de espera con la v4.4 (también probado en v4.5)

// 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);