web-dev-qa-db-ja.com

java.io.IOException:壊れたパイプ

現在、レガシーアプリケーションをJettyに移行しています。そして、壊れたパイプに関してはどういうわけか例外があります。

  • Java 6
  • 桟橋8.1.8
  • 春3.2.0

Glassfish WebアプリケーションをJettyに移行しようとしています。テスト環境では、ロードバランサーを使用しており、すべて正常に動作しています。クライアントは問題なく動作しています。

WARN  [2013-04-03 13:34:28,963] com.myapp.bbb.config.MvcDefaultConfig$1: Handler execution resulted in exception
! org.Eclipse.jetty.io.EofException: null
! at org.Eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.Java:914)
! at org.Eclipse.jetty.http.HttpGenerator.complete(HttpGenerator.Java:798)
! at org.Eclipse.jetty.server.AbstractHttpConnection.completeResponse(AbstractHttpConnection.Java:642)
! at org.Eclipse.jetty.server.Response.complete(Response.Java:1234)
! at org.Eclipse.jetty.server.Response.sendError(Response.Java:404)
! at org.Eclipse.jetty.server.Response.sendError(Response.Java:416)
! at org.springframework.web.servlet.DispatcherServlet.noHandlerFound(DispatcherServlet.Java:1111)
! at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:898)
! at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:856)
! at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:915)
! at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:811)
! at javax.servlet.http.HttpServlet.service(HttpServlet.Java:735)
! at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:796)
! at javax.servlet.http.HttpServlet.service(HttpServlet.Java:848)
! at org.Eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.Java:669)
! at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1336)
! at com.magnetdigital.maggy.dropwizard.head2get.Head2GetFilter.doFilter(Head2GetFilter.Java:22)
! at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1307)
! at com.yammer.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.Java:29)
! at org.Eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.Java:1307)
! at org.Eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.Java:453)
! at org.Eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.Java:229)
! at org.Eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.Java:1072)
! at org.Eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.Java:382)
! at org.Eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.Java:193)
! at org.Eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.Java:1006)
! at org.Eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.Java:135)
! at org.Eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.Java:116)
! at com.yammer.metrics.jetty.InstrumentedHandler.handle(InstrumentedHandler.Java:200)
! at org.Eclipse.jetty.server.handler.GzipHandler.handle(GzipHandler.Java:275)
! at com.yammer.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.Java:123)
! at org.Eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.Java:154)
! at org.Eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.Java:116)
! at org.Eclipse.jetty.server.Server.handle(Server.Java:365)
! at org.Eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.Java:485)
! at org.Eclipse.jetty.server.BlockingHttpConnection.handleRequest(BlockingHttpConnection.Java:53)
! at org.Eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.Java:926)
! at org.Eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.Java:988)
! at org.Eclipse.jetty.http.HttpParser.parseNext(HttpParser.Java:635)
! at org.Eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.Java:235)
! at org.Eclipse.jetty.server.BlockingHttpConnection.handle(BlockingHttpConnection.Java:72)
! at org.Eclipse.jetty.server.nio.BlockingChannelConnector$BlockingChannelEndPoint.run(BlockingChannelConnector.Java:298)
! at org.Eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.Java:608)
! at org.Eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.Java:543)
! at Java.lang.Thread.run(Thread.Java:662)
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:69)
! at Sun.nio.ch.IOUtil.write(IOUtil.Java:26)
! at Sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.Java:334)
! at org.Eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.Java:293)
! at org.Eclipse.jetty.server.nio.BlockingChannelConnector$BlockingChannelEndPoint.flush(BlockingChannelConnector.Java:253)
! at org.Eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.Java:850)
!... 44 common frames omitted

スタックトレースを確認すると、常に404リクエストによってこの例外がトリガーされるのを確認しました。

org.springframework.web.servlet.DispatcherServlet.noHandlerFound(DispatcherServlet.Java:1111)

  • この例外があるのはなぜですか?
  • マシンでこの例外をローカルで再現するにはどうすればよいですか?
22
Cemo

「壊れたパイプ」について私が経験した最も一般的な理由は、通信が完了する前に(ソケットを介して通信するペアの)1台のマシンがソケットの終端をシャットダウンしたことです。それらの約半分は、そのソケットで通信しているプログラムが終了したためです。

バイトを送信するプログラムがそれらを送信し、すぐにソケットをシャットダウンまたは終了する場合、バイトが送信および読み取られる前にソケットが機能を停止する可能性があります。

ソケットをシャットダウンする任意の場所に一時停止を入れてから、プログラムを終了させて​​、それが役立つかどうかを確認してください。

参考までに、「パイプ」と「ソケット」は、時々交換可能に使用される用語です。

32
arcy

私は@arcyに同意します、問題はクライアント側にあり、私の場合はnginxによるものでした、フロントエンドとしてnginxを使用しているので(負荷、sslなどを分散できるように...)、_proxy_pass http://127.0.0.1:8080_適切なリクエストをTomcatに転送します。

Nginx変数_proxy_read_timeout_にはデフォルト値である60秒で十分ですが、ピーク時には、セットアップでエラーが発生しますJava.io.IOException:Broken pipe変更根本原因(60秒で十分)が修正されるまで役立ちます。

注:ケースでもう少し詳しく説明できるように、新しい回答を作成しました(これは、インターネット上でこのエラーについてよく見た後に見つけた唯一の言及でした)

6
aseques

基本的に、ユーザーがブラウザーのタブを閉じているか、通信が完了する前に別のページに移動しているということです。 Webサーバー(Jetty)は、残りのバイトを送信できないため、この例外を生成します。

org.Eclipse.jetty.io.EofException: null
! at org.Eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.Java:914)
! at org.Eclipse.jetty.http.HttpGenerator.complete(HttpGenerator.Java:798)
! at org.Eclipse.jetty.server.AbstractHttpConnection.completeResponse(AbstractHttpConnection.Java:642)
! 

これは、アプリケーションロジック側のエラーではありません。これは、単にユーザーの行動によるものです。コード自体に問題はありません。

次の2つのことができます。

  1. この特定の例外は無視して、ログに記録しないようにしてください。
  2. 転送するデータが少なくなるように、コードをより効率的に/パックしてください。 (常にオプションではありません!)
2
Amrinder Arora

response.getBufferSize()を増やしてバッファサイズを取得し、転送するバイトと比較します。