4

我有一个REST服务,每天服务几乎20M的请求。我收到以下异常。这个问题是间歇性的,我无法将这个问题与请求的数量联系起来。在周末以及音量非常低的时候,我得到了这个例外。我通过检查setStaleConnectionCheckEnabled确保没有石碑连接。我使用的是httpclient 4.3.4SocketTimeoutException:读取超时httpclient

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

从日志,我可以看到,服务反应最请求的300 ms内,但它需要时间的客户端连接到服务本身,并收到时间响应,它已经跨越了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; 
} 

回答

0

这是它的权利,你是服务的拥有者?

如果是这样,我会检查为什么服务之间的数据包之间有一个暂停超过6秒,同时答复:由异常判断,连接是成功的。

可能的原因:服务端的定期连接速度较慢或者很长的完整GC。甚至是一个漫长的周期性的热身阶段(我不知道服务实施的细节,但可能对于一些特定的请求,服务必须花费超过6秒的时间来准备响应) - 换句话说,任何阻碍您服务的事情从6秒回答。

+0

是的,我拥有服务和客户端。从日志中,我可以看到服务在300毫秒内响应,但连接到服务本身需要时间,并且在收到响应时间后,它已经跨越了6秒的阈值,并且遇到了读取超时异常。 – Pankaj