【发布时间】:2012-03-04 00:34:42
【问题描述】:
我正在使用基于 Jetty 的 servlet 来执行 RPC,但我遇到了一个问题,即需要很长时间的请求会在服务器上引发以下异常:
2012-02-11 21:07:07,673 [btpool0-4] 调试 org.mortbay.log - 异常 java.net.SocketTimeoutException:读取超时 在 java.net.SocketInputStream.socketRead0(本机方法) 在 java.net.SocketInputStream.read(未知来源) 在 org.mortbay.io.ByteArrayBuffer.readFrom(ByteArrayBuffer.java:168) 在 org.mortbay.io.bio.StreamEndPoint.fill(StreamEndPoint.java:99) 在 org.mortbay.jetty.bio.SocketConnector$Connection.fill(SocketConnector .java:190) 在 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:277) 在 org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:203) 在 org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:357) 在 org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector. 爪哇:217) 在 org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool .java:475) 2012-02-11 21:07:07,674 [btpool0-4] 调试 org.mortbay.log - EOF
我尝试设置 Connection,Keep-Alive http 请求属性,但这没有任何效果,从我收集到的信息来看,http 1.1(我很确定我正在使用)默认情况下是持久的。
所以我认为有两种方法可以解决这个问题:
- 弄清楚如何防止超时异常 完全扔了
-
让客户端在不等待的情况下发出初始请求 响应,然后用单独的请求 ping 以检查何时 服务器完成了。
更新(2012 年 2 月 12 日):我按照 Tim 的建议设置了 maxIdleTime,这确实延长了超时发生前的时间,但随后我开始收到一个新异常:
2012-02-11 23:24:01,187 [btpool0-1] 调试 org.mortbay.log - 异常 java.io.IOException:现有连接被强制关闭 sun.nio.ch.SocketDispatcher.read0(Native Method) 的远程主机 sun.nio.ch.SocketDispatcher.read(Unknown Source) at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source) at sun.nio.ch.IOUtil.read(Unknown Source) at sun.nio.ch.SocketChannelImpl.read(Unknown Source) at org.mortbay.io.nio.ChannelEndPoint.fill(ChannelEndPoint.java:129) 在 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:277) 在 org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:203) 在 org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:357) 在 org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:329) 在 org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:475)
所以 Jetty 之外的东西正在终止连接,我怀疑很可能是防火墙。所以我最终做的是让服务器用多个线程处理请求;原始线程将立即响应 http 请求,并启动第二个线程以执行需要很长时间的操作。然后客户端将使用 http 请求进行轮询,以检查服务器上的操作何时完成。
【问题讨论】:
-
使请求更快。