web-dev-qa-db-fra.com

java.io.IOException: tuyau cassé

Nous sommes en train de migrer une application héritée vers Jetty. Et j'ai en quelque sorte une exception concernant un tuyau cassé.

  • Java 6
  • Jetée 8.1.8
  • Printemps 3.2.0

J'essaie de migrer une application Web Glassfish vers Jetty. Dans notre environnement de test, nous utilisons un équilibreur de charge et tout fonctionne correctement. Nos clients travaillent sans problème. 

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

Quand j'ai vérifié le stacktrace, j'ai vu que ces exceptions sont toujours déclenchées par une requête 404. 

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

  • Pourquoi ai-je cette exception? 
  • Comment puis-je reproduire cette exception sur ma machine localement? 
17
Cemo

La raison la plus courante pour un "tuyau cassé" est le fait qu’une machine (d’une paire communiquant via une prise) a fermé son extrémité de la prise avant la fin de la communication. Environ la moitié de ceux-ci étaient dus au fait que le programme communiquant sur ce socket était terminé. 

Si le programme qui envoie des octets les envoie et arrête immédiatement le socket ou s’arrête lui-même, il est possible que le socket cesse de fonctionner avant que les octets aient été transmis et lus. 

Essayez de mettre des pauses n'importe où lorsque vous fermez le socket et avant de permettre au programme de se terminer pour voir si cela peut vous aider.

Pour votre information: "pipe" et "socket" sont des termes qui sont parfois utilisés de manière interchangeable.

24
arcy

Je suis d’accord avec @arcy, le problème est du côté client, dans mon cas c’est à cause de nginx, laissez-moi élaborer J'utilise nginx comme interface (afin que je puisse distribuer load, ssl, etc ...) et en utilisant proxy_pass http://127.0.0.1:8080 pour transférer les demandes appropriées à Tomcat.

Il y a une valeur par défaut pour la variable nginx proxy_read_timeout de 60s qui devrait suffire, mais à certains moments de pointe, une erreur d'installation survient avec Java.io.IOException: Broken pipe. 60 devrait suffire) peut être corrigé.

NOTE: J'ai fait une nouvelle réponse pour pouvoir développer un peu plus mon cas (c'était la seule mention que j'ai trouvée à propos de cette erreur sur internet après avoir beaucoup regardé)

5
user322049

En gros, ce qui se passe, c’est que votre utilisateur ferme l’onglet du navigateur ou navigue vers une autre page avant la fin de la communication. Votre serveur Web (Jetty) génère cette exception car il lui est impossible d'envoyer les octets restants. 

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)
! 

Ce n'est pas une erreur du côté de la logique de votre application. Ceci est simplement dû au comportement de l'utilisateur. Il n'y a rien de mal dans votre code en soi.

Vous pouvez peut-être faire deux choses:

  1. Ignorez cette exception afin de ne pas la consigner.
  2. Rendez votre code plus efficace/compacté afin qu'il transmette moins de données. (Pas toujours une option!)
2
Amrinder Arora

augmentez le response.getBufferSize () Obtenez la taille du tampon et comparez avec les octets que vous voulez transférer! 

0