Клиентский запрос Java HTTP с заданным таймаутом

Я хотел бы сделать 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>

person Maxim Veksler    schedule 08.06.2010    source источник
comment
Какую библиотеку вы используете для всех функций HTTP?   -  person nojo    schedule 08.06.2010
comment
Спасибо за комментарий. Я обновил свой пост.   -  person Maxim Veksler    schedule 08.06.2010


Ответы (9)


Если вы используете Http Client версии 4.3 и выше, вам следует использовать следующее:

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
person Thunder    schedule 03.10.2013
comment
Спасибо! Я потратил по крайней мере 20 минут, пытаясь понять, как избавиться от устаревших команд, прежде чем найти ваш ответ. - person vextorspace; 17.04.2014
comment
Забыл SocketTimeout. Кроме того, означает ли default, что это значение по умолчанию для всех HttpClient, которые HttpClientBuilder из create () передаст через метод build()? Или только те, что проходят через setDefaultRequestConfig(requestConfig)? Я понимаю? - person ADTC; 14.07.2015
comment
@ADTC Ваш вопрос немного сбивает с толку :). Конфигурация запроса по умолчанию будет использоваться для всех экземпляров HttpPost, HttpGet, ..., использующих только этот HttpClient. Если вы создали другой экземпляр HttpClient, эта конфигурация запроса не будет использоваться с этим клиентом. - person Thunder; 26.03.2017

HttpParams устарел в новой библиотеке Apache HTTPClient. Использование кода, предоставленного Laz, приводит к предупреждению об устаревании.

Я предлагаю вместо этого использовать RequestConfig в вашем экземпляре HttpGet или HttpPost:

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);
person pmartin8    schedule 16.06.2014
comment
используя приведенный выше код ‹< SO - это не форум, и ответы меняются вверх / вниз из-за нескольких факторов, поэтому мы не знаем, на какой код вы имеете в виду. Не могли бы вы сказать что-нибудь вроде использования кода из ответа xyz? - person ADTC; 14.07.2015
comment
Кстати, аккуратный ответ. Но по сравнению с ответом Грома, какая разница между установкой RequestConfig в каждый HttpPost и установкой его по умолчанию в HttpClient? - person ADTC; 14.07.2015
comment
Да, вы правы, приведенный выше код относится к принятому ответу, который не должен меняться со временем. Я все равно обновлю свой ответ .. - person pmartin8; 15.07.2015

Похоже, вы используете 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;
}
person dbyrne    schedule 08.06.2010
comment
Это не повлияет на тайм-аут для HTTP-клиента Apache. - person laz; 09.06.2010
comment
Понятия тайм-аута в HttpURLConnection недостаточно. Если сервер начинает отвечать, но затем зависает, тайм-аут никогда не достигается. HttpClient от Apache - лучший выбор из-за этой разницы. - person benvolioT; 09.06.2011

Указанный метод с наивысшими показателями 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 для установки тайм-аута ожидания подключения от диспетчера подключений.

person Arun Thundyill Saseendran    schedule 03.11.2014

Я обнаружил, что установка параметров тайм-аута в 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);
      }
   }
}
person Kirby    schedule 17.06.2011

Об этом уже упоминалось выше в комментарии 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

Обратите внимание на бит, в котором говорится

Обратите внимание, что этот параметр может применяться только к соединениям, привязанным к определенному локальному адресу.

Я надеюсь, что это избавит кого-то от всей моей боли в голове. Это научит меня не читать документацию досконально!

person Dan Haynes    schedule 23.04.2013

Позже Оп заявил, что они использовали Apache Commons HttpClient 3.0.1.

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);
person rtaft    schedule 10.07.2014

HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout

Вы также можете определить требуемый тайм-аут.

person Mohammed Irfan Tirupattur    schedule 25.10.2012

person    schedule
comment
Что это значит? Таймаут чего он выставил? См. stackoverflow.com/questions / 3000767 / - person Maxim Veksler; 09.06.2010
comment
У Apache HttpClient есть два отдельных тайм-аута: тайм-аут, указывающий, как долго ждать установления TCP-соединения, и отдельный тайм-аут, как долго ждать следующего байта данных. HttpConnectionParams.setConnectionTimeout () - это первое, HttpConnectionParams.setSoTimeout () - второе. - person benvolioT; 09.06.2011
comment
Какой тайм-аут по умолчанию? 0 = бесконечно? - person Tobia; 03.10.2014
comment
http.connection.timeout Целое число Время ожидания до установления соединения. Нулевое значение означает, что тайм-аут не используется. - person maveroid; 29.02.2016
comment
Для будущих читателей: следует отметить, что упомянутые здесь классы теперь устарели (по состоянию на 2016-07-05), хотя, вероятно, это был хороший ответ, когда он был опубликован в 2010 году. См. Этот ответ: stackoverflow.com/a/19153314/192801 для чего-то более современного. - person FrustratedWithFormsDesigner; 05.07.2016