Apache HttpClient timeout exception after server response

I am using Apache HttpClient 4.1.2 for POST mail binary data (Java serialized objects) to the server.

Sometimes (in 20% of cases), the client will time out upon receipt of a response, even after the server responds correctly and registered the “200” response in its own logging.

Sequence of events:

  • Client POST data to the server (T0).
  • the server registers the receipt of data (T2, i.e. T + 2 seconds).
  • The server is processing data.
  • Server completes processing successfully (T45).
  • The server access log shows a completed response with a status of "200" (T46).
  • client blocks read response headers.
  • client timeout (T1800, i.e. 30 minutes after the POSTing request, which is used for the standard timeout).

The response body that the server returns is a small, like five bytes, text string, for example. "OK."

What could be here? I realized that time if the server did not respond; but the server responded and timely completed the correct answer, long before the client expired. The client seems to be "trying" to read the response, but it blocks and eventually disconnects.

The client runs on a computer running Windows XP; Ubuntu server Both versions of Java 6 (1.6.29 right now).

I create a new DefaultHttpClient object for each request and close it (and freeing other resources accordingly) after each request.

The client spends and deletes the body of the response object after the successful completion of the request, but we have not reached this point yet - the timeout occurs in the context of calling httpclient.execute (method).

Stack trace:

 java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:149) at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:110) at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:264) at org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(LoggingSessionInputBuffer.java:115) at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:98) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252) at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:281) at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:247) at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:645) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) at foo.StreamerClient.sendRequest(StreamerClient.java:312) at foo.StreamerClient.compressAndPostBinaryDataToFooServer(StreamerClient.java:287) at foo.StreamerClient.compressAndPostObjectsToFooServer(StreamerClient.java:238) 

This is where the wire level from the successful request is logged. The only difference from unsuccessful requests is that unsuccessful ones stop after registering binary data, and after half an hour they pop up again and register a timeout.

 [12-06 14:07:22.359][scheduler-3] D DefaultClientConnection Sending request: POST /foo/bar HTTP/1.1 [12-06 14:07:22.359][scheduler-3] D wire >> "POST /foo/bar HTTP/1.1[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Accept-Encoding: gzip,deflate[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Content-Type: application/octet-stream[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Content-Length: 401[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Host: foo.com[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Connection: Keep-Alive[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "User-Agent: Apache-HttpClient/4.1.2 (java 1.5)[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "Authorization: Basic fobar[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "[\r][\n]" [12-06 14:07:22.359][scheduler-3] D wire >> "[several lines of binary data]" [12-06 14:07:24.265][scheduler-3] D wire << "HTTP/1.1 200 OK[\r][\n]" [12-06 14:07:24.265][scheduler-3] D wire << "Date: Tue, 06 Dec 2011 03:07:23 GMT[\r][\n]" [12-06 14:07:24.265][scheduler-3] D wire << "Content-Type: text/plain;charset=ISO-8859-1[\r][\n]" [12-06 14:07:24.265][scheduler-3] D wire << "Content-Length: 2[\r][\n]" [12-06 14:07:24.265][scheduler-3] D wire << "Connection: close[\r][\n]" [12-06 14:07:24.265][scheduler-3] D wire << "[\r][\n]" 

Thanks.

+4
source share
1 answer

I noticed that the answer says

 Content-Length: 2 

But I do not see any content after the closing blank line [\r][\n] , which should not be counted as content. I think this is your problem. Either the server should say Content-Length: 0 , or not flush its buffers properly, or something like that.

In addition, in the headers, the server says:

 Connection: close 

Did the server close the connection or is the client still connected? If the server is not closed, it is somehow stuck.

Hope this helps.

+2
source

Source: https://habr.com/ru/post/1384917/


All Articles