SocketTimeoutException 和 Jetty 的问题

发布于 2025-01-04 13:14:50 字数 2284 浏览 1 评论 0原文

我正在使用基于 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(我很确定我正在使用)默认情况下是持久的。

所以我认为有两种方法可以尝试解决这个问题:

  1. 找出如何防止超时异常 完全抛出
  2. 让客户端发出初始请求而不等待 以获得响应,然后使用单独的请求 ping 来检查何时 服务器已完成。

    更新(2/12/2012):我按照 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(来源未知)位于 sun.nio.ch.IOUtil.readIntoNativeBuffer(来源未知)位于 sun.nio.ch.IOUtil.read(来源未知)位于 sun.nio.ch.SocketChannelImpl.read(来源未知)位于 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 请求进行轮询,以检查服务器上的操作何时完成。

I'm using a Jetty based servlet to do RPC and I'm having an issue where a request that takes a long time throws the following exception on the server:

2012-02-11 21:07:07,673 [btpool0-4] DEBUG org.mortbay.log - EXCEPTION
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at org.mortbay.io.ByteArrayBuffer.readFrom(ByteArrayBuffer.java:168)
at org.mortbay.io.bio.StreamEndPoint.fill(StreamEndPoint.java:99)
at org.mortbay.jetty.bio.SocketConnector$Connection.fill(SocketConnector
.java:190)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:277)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:203)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:357)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.
java:217)
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool
.java:475) 2012-02-11 21:07:07,674 [btpool0-4] DEBUG org.mortbay.log
- EOF

I tried setting the Connection,Keep-Alive http request property but that had no effect and from what I can gather, http 1.1 (which I'm pretty sure I'm using) is persistent by default.

So I think there are 2 ways I can try to address this:

  1. figure out how to prevent the timeout exception from being
    thrown at all
  2. Have the client issue the initial request without waiting
    for a response, and then ping with separate requests to check when
    the server is done.

    Update (2/12/2012): I set the maxIdleTime as Tim suggested and that did extend the time before the timeout occurred, but then I started getting a new exception:

2012-02-11 23:24:01,187 [btpool0-1] DEBUG org.mortbay.log - EXCEPTION
java.io.IOException: An existing connection was forcibly closed by the
remote host at sun.nio.ch.SocketDispatcher.read0(Native Method) at
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) at
org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:277) at
org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:203) at
org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:357) at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:329)
at
org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:475)

So something outside of Jetty was killing the connection, I suspect most likely a firewall. So what I ended up doing was making the server process the request with multiple threads; the original thread would immediately respond to the http request and a second thread would be kicked off to perform the action that was taking a long time. The client would then poll with http requests to check when the action on the server was complete.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悲念泪 2025-01-11 13:14:50

这是一个套接字超时,因此您在 HTTP 级别执行的任何操作都无法修复它 - 因此您的保持活动状态没有实现任何目标。

尝试在 SocketConnector 上设置 maxIdleTime

请参阅此处:http://docs.codehaus.org/display/JETTY/Configuring+Connectors ( 存档链接 )

This is a socket timeout, so nothing you do at the HTTP level can fix it - hence your keep alive not achieving anything.

Try setting the maxIdleTime on the SocketConnector

See here: http://docs.codehaus.org/display/JETTY/Configuring+Connectors ( archive link )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文