当使用带有 available() 方法的流返回相对较小的值时,Jetty HttpClient 在 POST 时崩溃
我使用 Jetty HttpClient 发送正文大约几 MB 的 POST 请求。我希望 Jetty 尽快开始传输请求,因此我使用 setRequestContentSource 方法。
问题是,当我使用任何带有 available() 方法的输入流返回相对较小的值(如 4096)时,Jetty 有时会崩溃并出现以下错误:
org.eclipse.jetty.io.EofException
at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:911)
at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
at java.lang.Thread.run(Thread.java:680)
Caused by:
java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:100)
at sun.nio.ch.IOUtil.write(IOUtil.java:71)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334)
at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:195)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:285)
at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:316)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:267)
at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:846)
at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
at java.lang.Thread.run(Thread.java:680)
它是不确定的,并且似乎将 Thread.sleep(10) 放入流的 read() 方法中解决问题。使用管道流时也可以修复此错误。这三件事让我认为这是某种竞争条件。
我认为这是 Jetty 中的错误,但我想确定在这种情况下我是否没有做任何奇怪的事情。
I use Jetty HttpClient to send POST request with body around few MB. I want Jetty to start streaming the request as soon as possible, so I use setRequestContentSource method.
The problem is that when I use any input stream with available() method returning relatively small value (like 4096) Jetty sometimes crash with following error:
org.eclipse.jetty.io.EofException
at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:911)
at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
at java.lang.Thread.run(Thread.java:680)
Caused by:
java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:100)
at sun.nio.ch.IOUtil.write(IOUtil.java:71)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334)
at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:195)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:285)
at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:316)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:267)
at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:846)
at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
at java.lang.Thread.run(Thread.java:680)
It's non deterministic and it seems that putting Thread.sleep(10) in stream's read() method fixes the problem. This error can be also fixed when piped streams are used. Those 3 things make me think that this is some kind of race condition.
I suppose that this is bug in Jetty, but I want to be sure if I'm not doing anything weird in such scenario.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我经常遇到这种情况,尤其是在通过代理并进行多部分操作时。
我知道这不会流式传输,而这正是您想要做的,但对我来说,我发布的文件有上限,所以它可以工作。
I get this a lot especially whilst going through a proxy and doing a multi part.
I know this doesn't stream it, which is what you want to do, but for me there is a cap on the files I am posting so it works.