Me gustaría hacer BIT (pruebas integradas) en varios servidores de mi nube. Necesito que la solicitud falle en un tiempo de espera grande.
¿Cómo debo hacer esto con Java?
Probar algo como el siguiente no parece funcionar.
public class TestNodeAliveness {
public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
client.getParams().setIntParameter("http.connection.timeout", 1);
HttpUriRequest request = new HttpGet("http://192.168.20.43");
HttpResponse response = client.execute(request);
System.out.println(response.toString());
return null;
}
public static void main(String[] args) throws ClientProtocolException, IOException {
nodeBIT("");
}
}
- EDITAR: aclare qué biblioteca se está utilizando -
Estoy usando httpclient de apache, aquí está la sección pom.xml relevante
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<type>jar</type>
</dependency>
java
http
timeout
network-protocols
Maxim Veksler
fuente
fuente
Respuestas:
import org.apache.http.client.HttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; ... // set the connection timeout value to 30 seconds (30000 milliseconds) final HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 30000); client = new DefaultHttpClient(httpParams);
fuente
Si está utilizando Http Client versión 4.3 y superior, debería utilizar esto:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build(); HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
fuente
SocketTimeout
. Además, ¿"predeterminado" significa que es predeterminado para todo loHttpClient
queHttpClientBuilder
from create () dará a través delbuild()
método? ¿O solo los que pasansetDefaultRequestConfig(requestConfig)
? ¿Tengo sentido?HttpParams está en desuso en la nueva biblioteca Apache HTTPClient. El uso del código proporcionado por Laz genera advertencias de obsolescencia.
Sugiero usar RequestConfig en su lugar en su instancia de HttpGet o HttpPost:
final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build(); httpPost.setConfig(params);
fuente
RequestConfig
en cadaHttpPost
en lugar de configurarlo como predeterminado en elHttpClient
?Parece que está utilizando la API de HttpClient, de la que no sé nada, pero podría escribir algo similar a esto utilizando el núcleo de Java.
try { HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); con.setRequestMethod("HEAD"); con.setConnectTimeout(5000); //set timeout to 5 seconds return (con.getResponseCode() == HttpURLConnection.HTTP_OK); } catch (java.net.SocketTimeoutException e) { return false; } catch (java.io.IOException e) { return false; }
fuente
Descubrí que establecer la configuración del tiempo de espera
HttpConnectionParams
yHttpConnectionManager
no resolvió nuestro caso. Estamos limitados a usar laorg.apache.commons.httpclient
versión 3.0.1.Terminé usando un
java.util.concurrent.ExecutorService
para monitorear laHttpClient.executeMethod()
llamada.Aquí hay un pequeño ejemplo autónomo
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.EntityEnclosingMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.concurrent.*; /** * @author Jeff Kirby * @since <pre>Jun 17, 2011</pre> */ public class Example { private static final String SITE = "http://some.website.com/upload"; private static final int TIME_OUT_SECS = 5; // upload a file and return the response as a string public String post(File file) throws IOException, InterruptedException { final Part[] multiPart = { new FilePart("file", file.getName(), file) }; final EntityEnclosingMethod post = new PostMethod(SITE); post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams())); final ExecutorService executor = Executors.newSingleThreadExecutor(); final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS); executor.shutdown(); if(futures.get(0).isCancelled()) { throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond"); } return post.getResponseBodyAsString(); } private static class KillableHttpClient implements Callable<Integer> { private final EntityEnclosingMethod post; private KillableHttpClient(EntityEnclosingMethod post) { this.post = post; } public Integer call() throws Exception { return new HttpClient().executeMethod(post); } } }
fuente
Dicho método con los más altos de Laz está obsoleto a partir de la versión 4.3. Por lo tanto, sería mejor utilizar el objeto de configuración de solicitud y luego construir el cliente HTTP
private CloseableHttpClient createHttpClient() { CloseableHttpClient httpClient; CommonHelperFunctions helperFunctions = new CommonHelperFunctions(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(306); cm.setDefaultMaxPerRoute(108); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(15000) .setSocketTimeout(15000).build(); httpClient = HttpClients.custom() .setConnectionManager(cm) .setDefaultRequestConfig(requestConfig).build(); return httpClient; }
El PoolingHttpClientConnectionManager es el usuario para establecer el número máximo predeterminado de conexiones y el número máximo de conexiones por ruta. Lo he configurado como 306 y 108 respectivamente. Los valores predeterminados no serán suficientes para la mayoría de los casos.
Para configurar el tiempo de espera: he utilizado el objeto RequestConfig. También puede establecer la propiedad Tiempo de espera de solicitud de conexión para configurar el tiempo de espera para esperar la conexión desde el Administrador de conexiones.
fuente
Esto ya fue mencionado en un comentario de benvoliot. anterior. Pero, creo que vale la pena una publicación de alto nivel porque seguro que me hizo rascar la cabeza. Estoy publicando esto en caso de que ayude a alguien más.
Escribí un cliente de prueba simple y el
CoreConnectionPNames.CONNECTION_TIMEOUT
tiempo de espera funciona perfectamente en ese caso. La solicitud se cancela si el servidor no responde.Sin embargo, dentro del código del servidor que estaba tratando de probar, el código idéntico nunca se agota.
Cambiarlo para que se agote el tiempo de espera en la actividad de conexión del socket (
CoreConnectionPNames.SO_TIMEOUT
) en lugar de la conexión HTTP (CoreConnectionPNames.CONNECTION_TIMEOUT
) solucionó el problema.Además, lea los documentos de Apache detenidamente: http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT
Note la parte que dice
Espero que eso le ahorre a alguien más todo el rascado de cabeza por el que pasé. ¡Eso me enseñará a no leer la documentación a fondo!
fuente
Op luego declaró que estaban usando Apache Commons HttpClient 3.0.1
HttpClient client = new HttpClient(); client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); client.getHttpConnectionManager().getParams().setSoTimeout(5000);
fuente
HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout
También puede definir su tiempo de espera requerido.
fuente