Установка времени ожидания в http-клиенте apache

Я использую HTTP-клиент Apache 4.3.2 для отправки запросов на получение. Что я сделал:

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(); 

И при отправке запроса:

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();
    }
}

Но некоторые из моих запросов по-прежнему требуют много времени для тайм-аута. Это трассировка стека исключения:

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)

Есть ли другое значение времени ожидания, которое я должен установить? Что я делаю неправильно?


person Majid Azimi    schedule 05.02.2014    source источник
comment
У меня такая же проблема, request.viaProxy(proxy).connectTimeout(1000) .socketTimeout(1000).execute() .returnContent().asString(StandardCharsets.UTF_8); возьмет даже 1 мунит!   -  person soulmachine    schedule 18.08.2015


Ответы (5)


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

//...
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);
//...

Это работало нормально.

person Jairton Junior    schedule 23.06.2017

Вот пример фрагмента кода для достижения цели:

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

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

Подробнее

person Tekle    schedule 14.02.2017

Вы можете попытаться прервать запрос с помощью HttpUriRequest#abort(), см. https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/методы/HttpUriRequest.html#abort%28%29. Однако было бы лучше установить тайм-аут, который не требует перехвата.

person static-max    schedule 24.04.2014

private static final Integer TIMEOUT = 300;
private static final Integer MILLISECONDS = 1000;

Конфигурация RequestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT * MILLISECONDS) .setConnectionRequestTimeout(TIMEOUT * MILLISECONDS).setSocketTimeout(TIMEOUT * MILLISECONDS).build();

httpClientBuilder.setDefaultRequestConfig(config); httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);

Мне не удается: время ожидания соединения истекло: ошибка подключения в течение 20 секунд, хотя я установил время 5 минут.

person madhusudhan    schedule 19.02.2020

.setSocketTimeout(1000) обозначает 1 секунду бездействия приложения при чтении пакетов данных, вызывающих это исключение.

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

Проверьте максимально возможное ограничение времени, которое вы ожидаете от своего приложения для операции чтения данных, например 50 секунд (крайний случай для объемных данных) --> затем обновите .setSocketTimeout(50000)

person DecKno    schedule 18.12.2015