Broken pipe no GUJ - sugestão de solução

0 respostas
Lavieri

Oi pessoal, não encontrei uma área aproprieada pra postar sobre isso, por isso estou postando aqui.

Ja recebi umas 2 ou 3 telas de broken pipe entre ontem e hoje, como voltei a acessar bastante, voltei a receber tal tela...

Passei recentemente por um problema de broken pipe que ocorria quando a conexão ficava ociosa.

Também uso mysql, e o time no meu servidor fechava qualquer conexão ociosa por mais de 20 segundos, gerando um broken pipe, tentei varias abordagem subi o tempo para 500 mas ai a noite rolava o mesmo problema, configurei o c3p0, porem ele fica restartando as conexão de tempo em tempo, o que gera um broken pipe para o usuário que der o asar de acessar na hora do restart...

Para solucionar, adicionar poucas linhas ao lado do meu sessionFactory ou EntityManagerFactory (depende do que usam).

sempre que preciso abrir um session, faço assim em volta da aberta da session, verifico se tem broken pipe e se for o caso reestabeleço a session.

Session session = HibernateUtils.reconnectIfNeed(sessionFactory.openSession());

usando esta abordagem, vcs podem testar inclusive dando kills, nas conexões abertas no pool de session, e da pra ver que a conexão é reestabelecida normalmente

aparentemente o problema ocorre pq o hibernate guarda em cache se a conexão esta aberta, e o teste de isOpen() só verifica se ela foi fechada por dentro do java, e não se a conexão esta realmente aberta, utilizando isActive() diretamente na conexão a verificação é feita in loco.

abaixo esta o código usado para reestabelecer a conexão se necessário

public class HibernateUtils {
	private static final Logger logger = Logger.getLogger(HibernateUtils.class);

	@SuppressWarnings("deprecation")
	public static Session reconnectIfNeed(Session session) {
		try {
			if (!session.connection().isValid(1)) {
				session.reconnect(null);
				logger.warn("connection was lost, reconnect was made");
			}
		} catch (SQLException ex) {
			logger.error("fail trying to reconnect to database", ex);
			throw new PersistenceException("fail trying to reconnect to database",ex);
		}
		return session;
	}
}

Ps.: Usei com MySQL Driver 5.1.8 tanto no MySQL Server 5.0 como no 5.1

segue abaixo o stack trace do broken que deu comigo...

<!-- BEGIN ERROR STACK TRACE
net.jforum.exceptions.ForumException: java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor244.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at net.jforum.Command.process(Command.java:114)
    at net.jforum.JForum.processCommand(JForum.java:217)
    at net.jforum.JForum.service(JForum.java:200)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
    at net.jforum.util.legacy.clickstream.ClickstreamFilter.doFilter(ClickstreamFilter.java:59)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
    at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.handler.StatisticsHandler.handle(StatisticsHandler.java:89)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Caused by: java.lang.reflect.InvocationTargetException
    ... 29 more
Caused by: net.jforum.exceptions.DatabaseException: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 1 ms ago.
    at sun.reflect.GeneratedConstructorAccessor50.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3246)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1917)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1885)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at net.jforum.dao.generic.GenericPostDAO.selectById(GenericPostDAO.java:83)
    at net.jforum.view.forum.PostAction.editSave(PostAction.java:754)
    ... 29 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 1 ms ago.
    ... 43 more
Caused by: java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3227)
    ... 37 more

URL is: /jforum.java?null
END ERROR STACK TRACE-->
Criado 13 de outubro de 2009
Respostas 0
Participantes 1