Рубрики
Без рубрики

Тайм-аут HttpClient

Как настроить тайм-аут для HttpClient – подключение и гнездо тайм-аутов, а также механизм для трудного тайм-аута текущих соединений http.

Автор оригинала: Eugen Paraschiv.

1. Обзор

Этот учебник покажет, как настроить тайм-аут с помощью системы Apache HttpClient 4 .

Если вы хотите копать глубже и узнать другие интересные вещи, которые вы можете сделать с HttpClient – над головой, чтобы основной httpClient учебник .

Дальнейшее чтение:

Управление подключением HttpClient

HttpClient 4 – Следуйте Перенаправления для POST

Расширенная конфигурация HttpClient

2. Настройка тайм-аутов перед HttpClient 4.3

2.1. Параметры строки сырья

Перед версией 4.3 вышел, HttpClient пришли с большим количеством параметров конфигурации, и все они могут быть установлены в общий, карта, как образом.

Были 3 параметра тайм-аута для настройки :

DefaultHttpClient httpClient = new DefaultHttpClient();

int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(
  CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000);
httpParams.setParameter(
  CoreConnectionPNames.SO_TIMEOUT, timeout * 1000);
httpParams.setParameter(
  ClientPNames.CONN_MANAGER_TIMEOUT, new Long(timeout * 1000));

2.2. API

Более важные из этих параметров, а именно первые два, также могут быть установлены с помощью более безопасного API:

DefaultHttpClient httpClient = new DefaultHttpClient();

int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(
  httpParams, timeout * 1000); // http.connection.timeout
HttpConnectionParams.setSoTimeout(
  httpParams, timeout * 1000); // http.socket.timeout

Третий параметр не имеет пользовательского сеттера в HttpConnectionParams , и он по-прежнему должны быть установлены вручную через наборПараметр метод.

3. Настройка тайм-аутов с использованием нового 4.3. строитель

Беглый, строитель API, представленный в 4.3 обеспечивает правильный способ установить тайм-ауты на высоком уровне :

int timeout = 5;
RequestConfig config = RequestConfig.custom()
  .setConnectTimeout(timeout * 1000)
  .setConnectionRequestTimeout(timeout * 1000)
  .setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = 
  HttpClientBuilder.create().setDefaultRequestConfig(config).build();

Это рекомендуемый способ настройки всех трех тайм-аутов безопасным и читаемым способом.

4. Тайм-аут Свойства Разъяснения

Теперь давайте объясним, что означают эти различные типы тайм-аутов:

  • Связь Тайм-аут ( http.connection.timeout ) – время установления связи с удаленным хостом
  • Выход на тайм-аут ( http.socket.timeout ) – время ожидания данных – после установления связи; максимальное время бездействия между двумя пакетами данных
  • Менеджер подключения Тайм-аут ( http.connection-manager.timeout ) – время ждать подключения от менеджера соединения/пула

Первые два параметра – подключение и разъем тайм-аутов – являются наиболее важными. Однако установление тайм-аута для получения соединения, безусловно, важно в сценариях высокой нагрузки, поэтому третий параметр не следует игнорировать.

5. Использование HttpClient

После его настройки мы можем использовать клиента для выполнения запросов HTTP:

HttpGet getMethod = new HttpGet("http://host:8080/path");
HttpResponse response = httpClient.execute(getMethod);
System.out.println(
  "HTTP Status of response: " + response.getStatusLine().getStatusCode());

С ранее определенным клиентом, подключение к хосту будет тайм-аут в 5 секунд. Кроме того, если соединение установлено, но данные не получены, тайм-аут также будет 5 дополнительных секунд .

Обратите внимание, что тайм-аут соединения приведет к org.apache.http.conn.ConnectTimeoutException бросали, в то время как разъем тайм-аут приведет к java.net.SocketTimeoutException .

6. Трудный тайм-аут

В то время как установление тайм-аутов по установлению соединения HTTP и не получению данных очень полезно, иногда нам нужно установить трудный тайм-аут для всего .

Например, загрузка потенциально большого файла вписывается в эту категорию. В этом случае соединение может быть успешно установлено, данные могут постоянно проходить, но мы все еще должны убедиться, что операция не проходит определенный порог времени.

HttpClient не имеет конфигурации, позволяющей установить общий тайм-аут для запроса; однако она обеспечивает прервать функциональность для запросов , так что мы можем использовать этот механизм для реализации простого механизма тайм-аута:

HttpGet getMethod = new HttpGet(
  "http://localhost:8080/httpclient-simple/api/bars/1");

int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        if (getMethod != null) {
            getMethod.abort();
        }
    }
};
new Timer(true).schedule(task, hardTimeout * 1000);

HttpResponse response = httpClient.execute(getMethod);
System.out.println(
  "HTTP Status of response: " + response.getStatusLine().getStatusCode());

Мы используем эту java.util.Timer и java.util.TimerTask создать простая отложенная задача, которая прерывает запрос HTTP GET после 5 секунд трудно тайм-аут.

7. Тайм-аут и DNS Раунд Робин – Что-то быть в курсе

Это довольно часто, что некоторые крупные домены будут использовать конфигурацию DNS круглый Робин – по существу, имея один и тот же домен отображается на нескольких IP-адресах . Это вводит новый вызов для тайм-аута против такого домена, просто из-за того, как HttpClient будет пытаться подключиться к этому домену, что тайм-аут:

  • HttpClient получает список IP-маршрутов в этот домен
  • он пытается первый – что тайм-аут (с тайм-аутов мы настраиваем)
  • он пытается второй – что также раз
  • и так далее …

Итак, как вы можете видеть – общая операция не будет тайм-аут, когда мы ожидаем, что . Вместо этого – это будет тайм-аут, когда все возможные маршруты приутомили. Более того – это произойдет совершенно прозрачно для клиента (если у вас нет журнала настроены на уровне DEBUG).

Вот простой пример, который можно запустить и воспроизвести эту проблему:

int timeout = 3;
RequestConfig config = RequestConfig.custom().
  setConnectTimeout(timeout * 1000).
  setConnectionRequestTimeout(timeout * 1000).
  setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = HttpClientBuilder.create()
  .setDefaultRequestConfig(config).build();

HttpGet request = new HttpGet("http://www.google.com:81");
response = client.execute(request);

Вы заметите, что логика повторной попытки с уровнем журнала DEBUG:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.212:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator - 
 Connect to www.google.com/173.194.34.212:81 timed out. Connection will be retried using another IP address

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.208:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator - 
 Connect to www.google.com/173.194.34.208:81 timed out. Connection will be retried using another IP address

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.209:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator - 
 Connect to www.google.com/173.194.34.209:81 timed out. Connection will be retried using another IP address
//...

8. Заключение

В этом учебнике обсуждался, как настроить различные типы тайм-аутов, доступных для HttpClient . Он также проиллюстрировал простой механизм для трудного тайм-аута текущего подключения HTTP.

Осуществление этих примеров можно найти в проект GitHub .