我应该从哪里开始调查 SocketTimeoutException:读取超时
Posted
技术标签:
【中文标题】我应该从哪里开始调查 SocketTimeoutException:读取超时【英文标题】:Where should I start investigating SocketTimeoutException: Read timed out 【发布时间】:2011-11-27 09:03:48 【问题描述】:我时不时地在日志中看到以下堆栈跟踪,其中HttpClient
套接字尝试从另一台服务器访问text/script
内容时超时。我的问题是我应该检查在 Linux 上运行在 Weblogic 上的 J2EE 应用程序的哪些配置设置?我正在专门寻找以下内容。
HttpClient
参数
Weblogic 超时参数或任何其他配置,如线程数等。
J2EE 应用程序设置,如 servlet 配置等
线程、文件处理程序和 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)
谢谢
我将使用以下调查结果更新我的问题。
HttpClient
上没有明确设置超时,这意味着 http
服务器的会话超时可能正在生效。
SO_TIMEOUT
for HttpClient
为 0,这意味着它应该无限期地等待。
【问题讨论】:
【参考方案1】:你应该调查一下
(a) 默认或显式HttpClient
读取超时,以正在使用的为准;
(b) 为什么服务器在这段时间内没有响应,如果应该(查看服务器日志),
(c) 否则为什么超时设置太短。许多超时设置得太短,例如几秒钟。它们应该是一分钟的一小部分,如果预期响应时间更长,则为预期响应时间的两倍或三倍。
【讨论】:
【参考方案2】:此处未涉及的另一个方面是防火墙。
我发现 SocketTimeoutExceptions 通常可能与未打开通信的端口或仅阻止来自选定计算机的通信的防火墙有关。
如果您正在调试问题,请确保您还调查了尝试通信的两台计算机之间是否存在防火墙,如果存在防火墙,请确保端口可用于两台计算机之间的通信。
关于防火墙相关问题的有趣之处在于,它不会让您知道服务器是否已关闭或没有响应。典型的行为是让客户端永远等待。所以你总是被留在黑暗中。服务器端口上的简单 telnet 应显示其是否可用/打开以进行通信。
希望这会有所帮助。
【讨论】:
【参考方案3】:曲目 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) 的建议进行更新
Track 3:Weblogic / 外部访问日志
您是否在服务器上启用了 HTTP 访问日志?这些失败的请求是否以任何响应字节大小显示,还是显示为 0 响应大小?返回什么错误码或HTTP状态码?
或者也许这些超时的根本没有记录在访问日志中?
在这里,我假设发生超时的外部服务器也是 Weblogic,如果不是 - 此问题针对其等效平台的外部服务器团队。
** 其他 **
通常线程转储会有所帮助,但线程转储应该在有超时问题的服务器上进行。您是客户端并且您已成功获得连接,之后在读取响应时超时。那么外部服务器是否过载?缺少线程? CPU高?并发请求过多?
【讨论】:
HttpClient 的 SO_TIMEOUT 为 0,这意味着它应该无限期等待。 @RHT:您可能是对的,但我会先致电getSOTimeout
确认您的价值。以上是关于我应该从哪里开始调查 SocketTimeoutException:读取超时的主要内容,如果未能解决你的问题,请参考以下文章