我应该在哪里开始调查SocketTimeoutException:读取超时

时间:2011-09-29 03:41:10

标签: java apache java-ee weblogic httpclient

我偶尔会在日志中看到以下堆栈跟踪,HttpClient套接字超时试图从另一台服务器访问text/script内容。我的问题是我应该在Linux上检查在Weblogic上运行的J2EE应用程序的配置设置是什么?我特意寻找以下内容。

  • JVM超时参数
  • HttpClient params
  • Weblogic超时参数或任何其他配置,如线程数等。
  • J2EE应用程序设置,如servlet config等。
  • 操作系统资源,如线程,文件处理程序和cpu
  • 可能影响套接字连接的任何其他配置设置
  • 线程转储会有帮助吗?

这是我的代码

HTTPResponse httpClientResponse;
//do some stuff
httpClientResponse.getStatusCode(); // this is where it fails

这是堆栈跟踪

java.net.SocketTimeoutException: Read timed out
at jrockit.net.SocketNativeIO.readBytesPinned(Native Method)
at jrockit.net.SocketNativeIO.socketRead(SocketNativeIO.java:32)
at java.net.SocketInputStream.socketRead0(SocketInputStream.java)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at HTTPClient.BufferedInputStream.fillBuff(BufferedInputStream.java:206)
at HTTPClient.BufferedInputStream.read(BufferedInputStream.java:126)
at HTTPClient.StreamDemultiplexor.read(StreamDemultiplexor.java:356)
at HTTPClient.RespInputStream.read(RespInputStream.java:147)
at HTTPClient.RespInputStream.read(RespInputStream.java:108)
at HTTPClient.Response.readResponseHeaders(Response.java:1123)
at HTTPClient.Response.getHeaders(Response.java:846)
at HTTPClient.Response.getStatusCode(Response.java:331)
at HTTPClient.RetryModule.responsePhase1Handler(RetryModule.java:92)
at HTTPClient.HTTPResponse.handleResponseImpl(HTTPResponse.java:872)
at HTTPClient.HTTPResponse.access$000(HTTPResponse.java:62)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.java:839)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.java:837)
at
HTTPClient.HttpClientConfiguration.doAction(HttpClientConfiguration.java:666)
at HTTPClient.HTTPResponse.handleResponse(HTTPResponse.java:837)
at HTTPClient.HTTPResponse.getStatusCode(HTTPResponse.java:242) 

由于

我将使用下面的调查结果更新我的问题。

  1. HttpClient上没有明确的超时设置,这意味着http 服务器的会话超时可能正在生效。
  2. SO_TIMEOUT HttpClient为0表示它应该无限期等待。

3 个答案:

答案 0 :(得分:16)

跟踪1

根据javadocs,Httpclient似乎没有Socket超时的默认值。要在更新中回答问题 - 会话超时在此处不起作用。会话超时时,Weblogic的默认值为30分钟。

服务器session timeout表示如果用户未访问服务器,HttpSession将在内存中保留的时间。

套接字超时是在将数据传输回调用方时保持服务器套接字打开的时间。这甚至可能是服务器仍在处理和写回数据,但它花费的时间相当长,而且客户端已经超时等待它。

有些链接表明这个默认值是60秒,但是javadocs没有说什么,无论如何你可以将这个值设置为120秒以查看是否有帮助

http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/params/HttpConnectionParams.html#setSoTimeout(int)

你需要的是计算超时时间 - 如果这很清楚的话。含义 - 在传出请求的30秒,60秒或5分钟后是否出现这些错误?

我会更改SO_Timeout并再试一次

跟踪2 - 操作系统参数

对于NDD值,建议使用BEA参数来控制传入连接保持打开的时间长度以及排队的数量等等。在Solaris上,这些是通过运行

获得的
/usr/sbin/ndd -get /dev/tcp tcp_time_wait_interval 
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q 
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q0 
/usr/sbin/ndd -get /dev/tcp tcp_ip_abort_interval 
/usr/sbin/ndd -get /dev/tcp tcp_keepalive_interval 

您可以在Oracle文档中查看Linux上的等效命令,以及它们应设置的值。在Solaris上,我的经验是默认值不够,需要将其提升为BEA(Oracle)建议

第3轨道:Weblogic /外部访问日志

您是否在服务器上启用了HTTP访问日志?这些失败的请求是否显示任何响应字节大小,或者它们是否显示0响应大小?返回了什么错误代码或HTTP状态代码?

或许这些超时的记录根本不会记录在访问日志中?

在这里,我假设发生超时的外部服务器也是Weblogic,如果没有 - 这个问题是针对外部服务器团队的同等平台。

**其他**

通常线程转储有帮助,但是应该在具有超时问题的服务器上进行线程转储。您是客户端,并且您已成功获得连接,之后在读取响应时超时。那么外部服务器是否过载?缺乏线程? CPU高?并发请求太多了?

答案 1 :(得分:0)

你应该调查

(a)默认或显式HttpClient读取超时,以使用者为准;

(b)为什么服务器在该时间段内没有响应,如果它应该(查看服务器日志),

(c)否则为什么超时设置得太短。许多超时设置得太短,例如几秒钟。它们应该是一分钟的一小部分,如果预期的响应时间更长,则是预期响应时间的两倍或三倍。

答案 2 :(得分:0)

此处未涉及的另一个方面是防火墙。

我发现SocketTimeoutExceptions通常可能与未打开通信的端口或阻止来自所选计算机的通信的防火墙相关。

如果您正在调试问题,请确保您还要调查两台机器之间是否有防火墙试图通信,如果有,请确保端口可用于两者之间的通信。

有关防火墙相关问题的有趣之处在于它不会让您知道服务器是否已关闭或未响应。典型的行为是让客户永远等待。所以你总是处于黑暗中。服务器端口上的简单telnet应显示其可用/开放是否可用于通信。

希望这会有所帮助。