4

Ich habe einen REST-Dienst, der fast ~ 20 M Anfrage pro Tag dient. Ich bekomme die folgende Ausnahme. Dieses Problem tritt nur sporadisch auf und ich konnte dieses Problem nicht mit dem Umfang der Anforderung in Verbindung bringen. Ich habe diese Ausnahme auch am Wochenende, wenn das Volumen sehr niedrig ist. Ich stelle sicher, dass es keine Stelenverbindung gibt, indem ich setStaleConnectionCheckEnabled überprüfe. Ich verwende httpclient 4.3.4SocketTimeoutException: Gelesen Zeitüberschreitung httpclient

Update: Einige weitere Details nach einer weiteren Analyse -

Aus dem Protokoll, kann ich sehen, dass die meisten Service des Antrags innerhalb von 300 ms reagiert, aber es dauerte seine Zeit für Client eine Verbindung zu Dienst selbst und durch die Zeit, die Antwort empfangen wurde, hatte es die Schwelle, die 6 Sekunden ist überschritten und rannte in Timeout Ausnahme gelesen.

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) 

Auftraggeber:

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

Antwort

0

Es ist es richtig, dass Sie der Eigentümer des Service sind?

Wenn ja, würde ich überprüfen, warum der Dienst eine Pause zwischen Paketen mehr als 6 Sekunden während der Antwort hatte: nach der Ausnahme zu urteilen, war die Verbindung erfolgreich.

Mögliche Gründe: periodisch langsame Verbindung oder ein sehr langer voller GC auf der Serviceseite. Oder sogar eine lange periodische Aufwärmphase (ich kenne die Details der Service-Implementierung nicht, aber wahrscheinlich musste der Service mehr als 6 Sekunden für eine bestimmte Anfrage mehr Zeit für die Vorbereitung der Antwort aufwenden) - mit anderen Worten, alles, was Ihren Service verhindert von der Antwort während 6 Sekunden.

+0

Ja, ich besitze sowohl Service als auch Client. Aus dem Protokoll kann ich sehen, dass der Dienst innerhalb von 300 ms geantwortet hat, aber es dauerte Zeit, sich mit dem Dienst selbst zu verbinden, und bis zum Empfang der Antwortzeit hatte er den Schwellenwert von 6 Sekunden überschritten und eine Auszeit-Ausnahmebedingung erhalten. – Pankaj