web-dev-qa-db-ja.com

Apache HTTPクライアントでタイムアウトを設定する

私はApache httpクライアント4.3.2を使用してgetリクエストを送信しています。私がしたことは:

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)

他に設定する必要があるタイムアウト値はありますか?何が悪いのですか?

20
Majid Azimi

この問題が発生したとき、各リクエストのタイムアウトを構成するようにリクエストを変更しました。

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

それはうまくいきました。

10
Jairton Junior

目標を達成するためのコードスニペットの例を次に示します。

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

これは、3つのタイムアウトすべてをタイプセーフで読み取り可能な方法で構成するための推奨方法です。

詳細はこちら

2
Tekle

HttpUriRequest#abort()でリクエストを中止しようとすることができます https://hc.Apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/Apache/http/client/methodsを参照) /HttpUriRequest.html#abort%28%29 。ただし、インターセプトを必要としないタイムアウトを設定する方が適切です。

0
static-max
private static final Integer TIMEOUT = 300;
private static final Integer MILLISECONDS = 1000;

RequestConfig config = RequestConfig.custom()。setConnectTimeout(TIMEOUT * MILLISECONDS).setConnectionRequestTimeout(TIMEOUT * MILLISECONDS).setSocketTimeout(TIMEOUT * MILLISECONDS).build();

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

失敗しました:接続がタイムアウトしました:時間を5分に設定しているにもかかわらず、接続エラーが20秒間続きます。

0
madhusudhan