http response timeout java
Estableciendo el tiempo de espera en el cliente http de apache (4)
Estoy usando Apache http client 4.3.2 para enviar solicitudes de obtención. Lo que he hecho es:
private final RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(1000)
.setConnectionRequestTimeout(1000)
.setSocketTimeout(1000)
.build();
private final HttpClient client = HttpClientBuilder.create()
.disableAuthCaching()
.disableAutomaticRetries()
.disableConnectionState()
.disableContentCompression()
.disableCookieManagement()
.disableRedirectHandling()
.setDefaultRequestConfig(requestConfig)
.build();
Y al enviar la solicitud:
HttpGet request = null;
try {
request = new HttpGet(url);
if (client.execute(request).getStatusLine().getStatusCode() == 200) {
/* do some work here */
}
} catch (Exception e) {
Logger.error(e);
} finally {
if (request != null) {
request.releaseConnection();
}
}
Pero algunas de mis solicitudes todavía tardan mucho tiempo en agotarse. Este es el rastro de la pila de excepción:
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:270)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:161)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.http.impl.conn.CPoolProxy.invoke(CPoolProxy.java:138)
at com.sun.proxy.$Proxy0.receiveResponseHeader(Unknown Source)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
¿Hay algún otro valor de tiempo de espera que debería establecer? ¿Qué estoy haciendo mal?
Aquí hay un ejemplo de fragmento de código para lograr el objetivo:
int timeout = 5;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(timeout * 1000)
.setConnectionRequestTimeout(timeout * 1000)
.setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
Esa es la forma recomendada de configurar los tres tiempos de espera de forma segura y legible.
Cuando tuve este problema, cambié mi solicitud para configurar el tiempo de espera en cada solicitud.
//...
HttpRequestBase request = new HttpGet(url); //or HttpPost
RequestConfig.Builder requestConfig = RequestConfig.custom();
requestConfig.setConnectTimeout(30 * 1000);
requestConfig.setConnectionRequestTimeout(30 * 1000);
requestConfig.setSocketTimeout(30 * 1000);
request.setConfig(requestConfig.build());
CloseableHttpResponse response = client.execute(request);
//...
Funcionó bien
Puede intentar cancelar la solicitud con HttpUriRequest # abort (), consulte https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html#abort%28%29 . Sin embargo, establecer un timemout que no requiera intercepción sería mejor.
.setSocketTimeout(1000)
denota 1 segundo de inactividad en la aplicación al leer los paquetes de datos causa esta excepción.
Puede probar esto ejecutando el código en modo de depuración y retrasar el paso al siguiente paso durante algún tiempo.
Verifique cuál es el límite de tiempo máximo posible que esperaría que su aplicación tome para la operación de lectura de datos, por ejemplo, 50 segundos (caso extremo para datos masivos) -> luego actualice .setSocketTimeout(50000)