SocketTimeoutException:读取超时的httpclient

时间:2016-07-24 18:18:20

标签: java sockets connection httpclient apache-commons-httpclient

我正在使用REST服务,每天提供近20 M的请求。我收到以下异常。此问题是间歇性的,我无法将此问题与请求的大小相关联。我在周末也遇到了这个例外,因为音量非常低。我通过检查setStaleConnectionCheckEnabled确保没有石碑连接。我正在使用httpclient 4.3.4

更新:进一步分析后的更多细节 -

从日志中,我可以看到该服务在300毫秒内响应了大部分请求,但客户端需要时间连接到服务本身,并且在收到响应时,它已超过阈值6秒并运行进入读取超时异常。

getCause(): 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 sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:891)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284)
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:261)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:220)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:164)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:139)
at com.sample.SampleClient.doGet(SampleClient.java:137)

客户:

public MyRespBean doGet(String host, String path, List<NameValuePair> nameValuePairs, Map<String, String> headers, AuthParams authParams)
throws URISyntaxException, IOException
{
  RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).setStaleConnectionCheckEnabled(true).build();
  CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
  URI uri = buildUri(host, path, nameValuePairs);
  HttpGet httpGet = new HttpGet(uri);
  httpGet.setHeader("Connection", "close");
  addHeaders(httpGet, headers, authParams);
 **//Error occurs at the following line**
 MyRespBean respBean = (MyRespBean)httpClient.execute(httpGet, new SimpleResponseHandler());
  httpClient.close();
  return respBean;
}

1 个答案:

答案 0 :(得分:1)

您是该服务的所有者是对的吗?

如果是这样,我会在回复时检查服务在数据包之间暂停超过6秒的原因:通过异常判断,连接成功。

可能的原因:在服务端定期减慢连接或使用非常长的完整GC。或者甚至是一个长期的定期预热阶段(我不知道服务实现的细节,但可能是某些特定的请求,服务必须花费超过6秒来准备响应) - 换句话说,任何阻止你的服务在6秒内回答。