Я хотел бы сделать BIT (встроенные тесты) для ряда серверов в моем облаке. Мне нужно, чтобы запрос завершился ошибкой при большом тайм-ауте.
Как мне сделать это с помощью java?
Попытка сделать что-то подобное ниже, похоже, не работает.
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("");
}
}
- РЕДАКТИРОВАТЬ: уточнить, какая библиотека используется -
Я использую httpclient из apache, вот соответствующий раздел pom.xml
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<type>jar</type>
</dependency>
java
http
timeout
network-protocols
Максим Векслер
источник
источник
Ответы:
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);
источник
Если вы используете Http Client версии 4.3 и выше, вам следует использовать следующее:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build(); HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
источник
SocketTimeout
. Кроме того, означает ли "default" это значение по умолчанию для всего,HttpClient
чтоHttpClientBuilder
передастbuild()
метод from create () ? Или только те, которые проходятsetDefaultRequestConfig(requestConfig)
? Я понимаю?HttpParams устарел в новой библиотеке Apache HTTPClient. Использование кода, предоставленного Laz, приводит к предупреждению об устаревании.
Я предлагаю вместо этого использовать RequestConfig в вашем экземпляре HttpGet или HttpPost:
final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build(); httpPost.setConfig(params);
источник
RequestConfig
в каждыйHttpPost
и по умолчанию вHttpClient
?Похоже, вы используете HttpClient API, о котором я ничего не знаю, но вы можете написать что-то подобное, используя ядро 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; }
источник
Я обнаружил , что установка времени из настроек в
HttpConnectionParams
иHttpConnectionManager
не решало наше дело. Мы ограничены использованиемorg.apache.commons.httpclient
версии 3.0.1.В итоге я использовал
java.util.concurrent.ExecutorService
для отслеживанияHttpClient.executeMethod()
звонка.Вот небольшой автономный пример
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); } } }
источник
Указанный метод с наивысшими показателями Laz устарел начиная с версии 4.3. Следовательно, было бы лучше использовать объект конфигурации запроса, а затем создать 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; }
PoolingHttpClientConnectionManager позволяет пользователю установить максимальное количество подключений по умолчанию и максимальное количество подключений на маршрут. Я установил 306 и 108 соответственно. В большинстве случаев значений по умолчанию будет недостаточно.
Для установки тайм-аута: я использовал объект RequestConfig. Вы также можете установить свойство Connection Request Timeout для установки тайм-аута ожидания соединения от диспетчера соединений.
источник
Об этом уже упоминалось в комментарии Benvoliot выше. Но я думаю, что это стоит поста на высшем уровне, потому что он наверняка заставил меня почесать голову. Я отправляю это на случай, если это поможет кому-то другому.
Я написал простой тестовый клиент, и
CoreConnectionPNames.CONNECTION_TIMEOUT
в этом случае тайм-аут отлично работает. Запрос отменяется, если сервер не отвечает.Однако внутри серверного кода, который я пытался протестировать, время ожидания идентичного кода никогда не истекло.
Изменение его на тайм-аут для активности соединения сокета (
CoreConnectionPNames.SO_TIMEOUT
) вместо HTTP-соединения (CoreConnectionPNames.CONNECTION_TIMEOUT
) устранило проблему для меня.Также внимательно прочтите документы Apache: http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT
Обратите внимание на бит, который говорит
Я надеюсь, что это избавит кого-то от всей моей боли в голове. Это научит меня не читать документацию досконально!
источник
Позже Оп заявил, что они использовали Apache Commons HttpClient 3.0.1.
HttpClient client = new HttpClient(); client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); client.getHttpConnectionManager().getParams().setSoTimeout(5000);
источник
HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout
Вы также можете определить требуемый тайм-аут.
источник