Java 在 apache http 客户端中设置超时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21576414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:28:08  来源:igfitidea点击:

Setting time out in apache http client

javatimeoutapache-httpcomponents

提问by Majid Azimi

I'm using Apache http client 4.3.2 to send get requests. What I have done is:

我正在使用 Apache http 客户端 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(); 

And when sending request:

当发送请求时:

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

But some of my requests still takes long time to timeout. This is stack trace of exception:

但是我的一些请求仍然需要很长时间才能超时。这是异常的堆栈跟踪:

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)

Is there any other time out value I should set? What am I doing wrong?

我应该设置任何其他超时值吗?我究竟做错了什么?

回答by static-max

You can try to abort the request with HttpUriRequest#abort(), see https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html#abort%28%29. However, setting a timemout that requires no intercepting would be nicer.

您可以尝试使用 HttpUriRequest#abort() 中止请求,请参阅https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html #abort%28%29。但是,设置一个不需要拦截的超时时间会更好。

回答by DecKno

.setSocketTimeout(1000)denotes 1 second of inactivity in application in reading the data packets causes this exception.

.setSocketTimeout(1000)表示应用程序在读取数据包时 1 秒不活动会导致此异常。

You can test this by running the code in debug mode and delay moving to next step for some time.

您可以通过在调试模式下运行代码并将移动到下一步的时间延迟一段时间来测试这一点。

Check what is the maximum possible time limit you would expect your application to take for data read operation, for example 50 seconds (extreme case for bulk data)--> then update .setSocketTimeout(50000)

检查您希望应用程序进行数据读取操作的最大可能时间限制是多少,例如 50 秒(批量数据的极端情况)--> 然后更新 .setSocketTimeout(50000)

回答by Tekle

Here is a code snippet example to achieve the goal :

这是实现目标的代码片段示例:

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

That is the recommended way of configuring all three timeouts in a type-safe and readable manner.

这是以类型安全和可读的方式配置所有三个超时的推荐方法。

Here is the full detail

这是完整的细节

回答by Jairton Junior

When I had this problem I changed my request to configure the timeout on each request.

当我遇到这个问题时,我改变了我的请求来配置每个请求的超时时间。

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

It worked fine.

它工作得很好。

回答by madhusudhan

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

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

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

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

I am geting failed: Connection timed out: connect error for 20 seconds even though i have set time 5 minutes.

我失败了:连接超时:即使我将时间设置为 5 分钟,连接错误仍持续 20 秒。