![](/img/trans.png)
[英]Read time out in Apache HTTP Client but request runs fine with curl
[英]Setting time out in apache http client
我正在使用 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();
發送請求時:
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)
我應該設置其他超時值嗎? 我究竟做錯了什么?
當我遇到這個問題時,我更改了我的請求以配置每個請求的超時。
//...
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);
//...
它工作得很好。
這是實現目標的代碼片段示例:
int timeout = 5;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(timeout * 1000)
.setConnectionRequestTimeout(timeout * 1000)
.setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
這是以類型安全和可讀的方式配置所有三個超時的推薦方法。
您可以嘗試使用 HttpUriRequest#abort() 中止請求,請參閱https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.html #中止%28%29 。 但是,設置一個不需要攔截的超時會更好。
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);
我失敗了:連接超時:連接錯誤 20 秒,即使我已將時間設置為 5 分鍾。
.setSocketTimeout(1000)
表示應用程序在讀取數據包時不活動 1 秒會導致此異常。
您可以通過在調試模式下運行代碼來測試這一點,並延遲一段時間進入下一步。
檢查您希望應用程序進行數據讀取操作的最大可能時間限制是多少,例如 50 秒(批量數據的極端情況)-> 然后更新.setSocketTimeout(50000)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.