Apache服务器如何响应请求,服务器响应后的Apache HttpClient超时异常

我使用Apache HttpClient 4.1.2将压缩后的二进制数据(序列化Java对象)发送到服务器 .

有时(20%的时间)客户端会在收到响应时超时,并在自己的日志记录中记录了"200"响应 .

事件的顺序是:

client将数据POST到服务器(T0) .

服务器记录数据的接收(T2,即T 2秒) .

服务器处理数据 .

服务器记录成功完成处理(T45) .

服务器访问日志显示已完成的响应,其状态为"200"(T46) .

客户端阻止读取响应头 .

客户端超时(T1800,即POSTing请求后30分钟,这是我使用的标准超时) .

服务器返回的响应主体是一个小的,如五个字节或更少的纯文本字符串,例如, “好” .

这里可以发生什么?如果服务器没有响应,我可以理解超时;但服务器已响应,并在客户端超时之前及时记录了正确的响应 . 客户似乎“试图”阅读响应但阻止并最终超时 .

客户端在Windows XP计算机上运行;服务器是Ubuntu . 两者都运行Java 6(现在1.6.29) .

我正在为每个请求创建一个新的 DefaultHttpClient 对象,并在每个请求后关闭它(并适当地释放其他资源) .

请求成功完成后,客户端会消耗并处理响应实体主体,但我们还没有达到这一点 - 超时发生在 httpclient.execute (方法)调用的上下文中 .

堆栈跟踪:

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)

这是成功请求的线路级别记录 . 与不成功请求的唯一区别是,在记录二进制数据后,不成功的请求会停止,半小时后会再次弹出并记录超时 .

[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]"

谢谢 .

你可能感兴趣的:(Apache服务器如何响应请求)