Broken pipe.. nada resolve!

22 respostas
dahenz

Estou com um problema que jaz fazem alguns dias que não consigo resolver.....

Minha aplicação tem problemas de inatividade de conexão .... o famoso Broken Pipe.....

Configurei o C3p0 da seguinte forma:

hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider
hibernate.c3p0.min_size = 1
hibernate.c3p0.max_size = 20
hibernate.c3p0.max_statements = 0
hibernate.c3p0.idle_test_period = 100
hibernate.c3p0.timeout = 50
hibernate.c3p0.interactive_timeout = 10

Também criei um validador de conexões em uma classe separada:

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;
	}

}

Com tudo isso ainda ocorre o erro: Broken Pipe... Alguma luz???

22 Respostas

fabiozoroastro

Você já deu uma lida nesse post?

dahenz

hehe não tenho acesso à blogs aqui na empresa… :slight_smile:

mas no almoço vou entrar neste link…

fabiozoroastro

Como sou uma pessoa de bom coração, segue o post. :lol:

Segue, inclusive, os comentários.

dahenz

Opa Fábio!!! Valew pela força... O post é muito esclarecedor.... Minha configuração do c3p0 é igual ao mostrado nele... e mesmo assim traz o erro broken pipe.... Este post informa que transações que não utilizam commit ou rollback podem trazer problemas, que não meu caso, são tratados corretamente....

Eu faço uma consulta na tela inicial do sistema como segue:

<%
   VersaoViewebDAO versaoViewebDAO = new VersaoViewebDAO();
   VersaoViewebBean versaoViewebBean = new VersaoViewebBean();
   
   versaoViewebBean = versaoViewebDAO.getInformacoesSistema();
	
%>

<title>
   <%  	
   out.print(versaoViewebBean.getSistema());
   %>
</title>

Nela já da o erro!!!

No DAO a conexão é feita através de uma session do hibernate..... O que faço???

G

Nosso colega Lavieri já havia proposto uma solução (link abaixo).

http://www.guj.com.br/posts/list/141603.java

dahenz

Oi Garcia!!! Essa solução já foi utilizada… e não funcionou…

Quando dou um kill na conexão do banco, ela reconecta… mas quando ocorre broken pipe não…

Essa solução não será usada, pois perco em desempenho tambem…

dahenz

Tentei fazer o teste hoje.... e novamente:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: An exception occurred processing JSP page /index.jsp at line 25

22:    VersaoViewebDAO versaoViewebDAO = new VersaoViewebDAO();
23:    VersaoViewebBean versaoViewebBean = new VersaoViewebBean();
24:    
25:    versaoViewebBean = versaoViewebDAO.getInformacoesSistema();
26: 	
27: %>
28: 


Stacktrace:
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:524)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:435)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

org.hibernate.exception.JDBCConnectionException: could not execute query
	org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:74)
	org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
	org.hibernate.loader.Loader.doList(Loader.java:2214)
	org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
	org.hibernate.loader.Loader.list(Loader.java:2090)
	org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
	org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
	org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
	br.com.eucatur.vieweb.dao.VersaoViewebDAO.getInformacoesSistema(VersaoViewebDAO.java:19)
	org.apache.jsp.index_jsp._jspService(index_jsp.java:78)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 50.482.758 milliseconds ago.  The last packet sent successfully to the server was 50.482.758 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
	sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
	com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
	com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3313)
	com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1940)
	com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
	com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
	com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
	com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2228)
	org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
	org.hibernate.loader.Loader.getResultSet(Loader.java:1778)
	org.hibernate.loader.Loader.doQuery(Loader.java:662)
	org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
	org.hibernate.loader.Loader.doList(Loader.java:2211)
	org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
	org.hibernate.loader.Loader.list(Loader.java:2090)
	org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
	org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
	org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
	br.com.eucatur.vieweb.dao.VersaoViewebDAO.getInformacoesSistema(VersaoViewebDAO.java:19)
	org.apache.jsp.index_jsp._jspService(index_jsp.java:78)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

java.net.SocketException: Broken pipe
	java.net.SocketOutputStream.socketWrite0(Native Method)
	java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
	java.net.SocketOutputStream.write(SocketOutputStream.java:136)
	java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
	java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
	com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3294)
	com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1940)
	com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
	com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
	com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
	com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2228)
	org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
	org.hibernate.loader.Loader.getResultSet(Loader.java:1778)
	org.hibernate.loader.Loader.doQuery(Loader.java:662)
	org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
	org.hibernate.loader.Loader.doList(Loader.java:2211)
	org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
	org.hibernate.loader.Loader.list(Loader.java:2090)
	org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
	org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
	org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
	br.com.eucatur.vieweb.dao.VersaoViewebDAO.getInformacoesSistema(VersaoViewebDAO.java:19)
	org.apache.jsp.index_jsp._jspService(index_jsp.java:78)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.14 logs.
Apache Tomcat/6.0.14

Minha conexão é feita da seguinte forma:

public class MySQLDAOFactory extends MySQLDAO{

	private static PoolConnection pool;
	private static SessionFactory factory;
	private static Logger log = Logger.getLogger(MySQLDAOFactory.class);
	
	private static ThreadLocal<Session> sessions = new ThreadLocal<Session>();
	
	static {
		
		Properties p = new Properties();
		p.setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
		p.setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
		p.setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQLMyISAMDialect");
		p.setProperty( "hibernate.connection.driver_class", "com.mysql.jdbc.Driver");

		String os = System.getProperty("os.name");
		if (!os.equals("Windows XP")){

			p.setProperty( "hibernate.connection.url", "*********");
			p.setProperty( "hibernate.connection.username", "***********" );
			p.setProperty( "hibernate.connection.password", "********" );

		} else {

			p.setProperty( "hibernate.connection.url", "*************");
			p.setProperty( "hibernate.connection.username", "*****" );
			p.setProperty( "hibernate.connection.password", "******" );

		}

		AnnotationConfiguration cfg = new AnnotationConfiguration();
				
		cfg.addAnnotatedClass(UsuarioBean.class);
		cfg.addAnnotatedClass(EventoBean.class);
		cfg.addAnnotatedClass(ImovelBean.class);
		cfg.addAnnotatedClass(CidadeBean.class);
		cfg.addAnnotatedClass(ConsultaHistoricoBean.class);
		cfg.addAnnotatedClass(DocumentosFinanceiroBean.class);
		cfg.addAnnotatedClass(ISessionBean.class);
		cfg.addAnnotatedClass(HistoricoBean.class);
		cfg.addAnnotatedClass(PerfilBean.class);
		cfg.addAnnotatedClass(ObjetoBean.class);
		cfg.addAnnotatedClass(VersaoViewebBean.class);
		cfg.addAnnotatedClass(RegiaoBean.class);
		cfg.addAnnotatedClass(CargoBean.class);
		cfg.addAnnotatedClass(EmpresaBean.class);
		cfg.addAnnotatedClass(RegraBean.class);
		cfg.addAnnotatedClass(SupervisorBean.class);
		cfg.addAnnotatedClass(CobrancaBean.class);
		cfg.addAnnotatedClass(EventosRegraBean.class);	
		cfg.addAnnotatedClass(PosicaoBean.class);
		cfg.addAnnotatedClass(TipoEventoBean.class);
		
		Configuration conf = cfg.setProperties(p);

		factory = conf.buildSessionFactory();
		
	}
	
	public static Session openSession(boolean isSessionDB) throws ClassNotFoundException, SQLException{

		if (sessions.get() != null){
			
			log.error("Já existe uma sessão para essa Thread!");
			
		}
		
		log.debug("Abrindo uma nova sessão...");
		//sessions.set(HibernateUtils.reconnectIfNeed(factory.openSession()));
		
		sessions.set(factory.openSession());
		
		return sessions.get();
			
	}
	
	public static void closeCurrentSession(){
		
		log.debug("Fechando sessão...");
		sessions.get().close();
		sessions.set(null);
		
	}
	
	public static Session currentSession(){
		
		return sessions.get();
		
	}
	
	public static Statistics getStatistics() {
		
		return factory.getStatistics();
		
	}
		
	public static Connection getMySQLConnection() throws ClassNotFoundException, SQLException{
		
		String driver = "com.mysql.jdbc.Driver";

		String url = "";
		String user = "";
		String password = "";		

		String os = System.getProperty("os.name");
		if (!os.equals("Windows XP")){

			url = "**********";
			user = "*******";
			password = "********";		

		} else {

			url = "****************";
			user = "********";
			password = "********";		

		}

		pool = new PoolConnection(driver, url, user, password, 1, 10, true);

		Connection con;
		con = pool.getConnection();
		con.setAutoCommit(false);
						
		return con;
		
	}

	
}

Na minha conexão, eu guardo as sessões em uma coleção de threads locais!!! Antes de alocar uma sessão na thread desejada, eu verifico se essa sessão é valida utilizando um método em uma classe de testes... seguindo alguns posts daqui do guj:

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;
	}

}

Além deste teste ainda tenho a configuração do c3p0 no hibernate.properties que verifica se a conexão está ativa a cada 100 segundos

hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider
hibernate.c3p0.min_size = 1
hibernate.c3p0.max_size = 20
hibernate.c3p0.max_statements = 0
hibernate.c3p0.idle_test_period = 100
hibernate.c3p0.timeout = 50
hibernate.c3p0.interactive_timeout = 10

Ocorre o erro mesmo assim... Agora pergunto:Esta collection de sessões não pode ser um problema? Pois o teste verificado pode ser feito em uma sessão e o sistema chamando outra..... Alguém tem uma solução para isso???

Obrigado

saoj

maxIdleTime = 10 resolve.

dahenz

saoj, fiz a alteração que voce me sujeriu, adicionei maxIdleTime=10…

O erro parece que mudou…

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 50.196.182 milliseconds ago. The last packet sent successfully to the server was 50.196.182 milliseconds ago. is longer than the server configured value of ‘wait_timeout’. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property ‘autoReconnect=true’ to avoid this problem.

Pelo menos o ultimo pacote recebido com sucesso foi em 50.196.182 milliseconds…

hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider hibernate.c3p0.min_size = 1 hibernate.c3p0.max_size = 20 hibernate.c3p0.max_statements = 0 hibernate.c3p0.idle_test_period = 100 hibernate.c3p0.timeout = 50 hibernate.c3p0.interactive_timeout = 10 hibernate.c3p0.maxIdleTime = 10

Cara estou ficando louco :lol: hehe

Paulo_Silveira

Ola!

Tres sugestoes:

  1. Pela stacktrace nao parece que o C3P0 esta sendo ativado. Ele esta aparecendo no log quando voce sobe o SessionFactory? Pode ser um erro de digitacao, lugar doa rquivo de configuracao estar errado, etc.
  2. Force a validacao da conexao como falei no blog “Se você quer ter uma confiabilidade de 100% em relação a suas conexões, você pode configurar a variável testConnectionOnCheckout no arquivo c3p0.properties”. Esse c3p0.properties voce tambem vai deixar no seu classpath (WEB-INF/classes se for web, por exemplo).
  3. na sua string de conexao, adicione ?autoReconnect=true ao final dela. exemplo “jdbc:mysql//host/banco?autoReconnect=true”

avise a gente!

dahenz

Ok… vou fazer isso…

Avisarei durante o dia … e amanhã pela manhã será o teste derradeiro… hehe :slight_smile:

dahenz

Uma coisa que percebi… eu não tinha a opção:

p.setProperty( "hibernate.connection.url", "jdbc:mysql://banco/db?autoReconnect=true");

autoReconnect=true;;;;;

Agora só esperar…

Paulo_Silveira

de um toque

mas mesmo sem o autoReconnect deveria funcionar!

boa sorte!

dahenz

Paulo… Desculpe ficar encomodando… mas hoje deu erro novamente… Prestei atenção no seu penúltimo post… lá você diz para criar um arquivo c3p0.properties para colocar as informações…

O código abaixo estou colocando no hibernate.properties… então está errado???

hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider hibernate.c3p0.min_size = 1 hibernate.c3p0.max_size = 20 hibernate.c3p0.max_statements = 0 hibernate.c3p0.idle_test_period = 100 hibernate.c3p0.timeout = 50 hibernate.c3p0.interactive_timeout = 10 hibernate.c3p0.maxIdleTime = 10

Devo criar um arquivo c3p0.properties na minha pasta classes???

Obrigado pela ajuda amigo…

dahenz

Criei o arquivo c3p0.properties e coloquei as informações como seguem:

hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider hibernate.c3p0.min_size = 1 hibernate.c3p0.max_size = 20 hibernate.c3p0.max_statements = 0 hibernate.c3p0.idle_test_period = 100 hibernate.c3p0.timeout = 50 hibernate.c3p0.interactive_timeout = 10 hibernate.c3p0.maxIdleTime = 10

E ainda não funciona!!! Não funciona de jeito nenhum…

Como sei se este arquivo está sendo utilizado???

Alguém me ajude… obrigado!!

Paulo_Silveira

oi dahhenz

no c3p0.properties coloque apenas:

testConnectionOnCheckout=true

o restante deixe no hbiernate.properties/xml.

verifique atraves do log do c3p0 que ele esta subindo e de que esta usando as opcoes que voce setou (ligue o debug level dele)

dahenz

Oi Paulo…

Para mim ligar o debug do c3p0 eu adiciono esta linha no hibernate.properties?

hibernate.c3p0.debugUnreturnedConnectionStackTraces=false

Obrigado

Paulo_Silveira

Nao daian, provavelmente no log4j.xml mesmo

dahenz

Hum Paulo… qual é a linha no log4j que trata do debug do c3p0??

Paulo_Silveira

daian

defina que o log com.mchange.v2.log.MLog va pro nivel de INFO, ai ele vai imprimir tudo que esta fazendo. (baseie-se em algum log4j.xml que voce ja tenha)

aqui tem mais detalhes
http://www.mchange.com/projects/c3p0/index.html#configuring_logging

dahenz

Paulo… Pelo material contigo no link, o que eu entendi é que: o c3p0´s logging utiliza o famoso log4j, portanto para forçar o INFO para o log4j devo escrever a linha de comando com.mchange.v2.log.log4j.Log4jMLog dentro do arquivo c3p0.properties???

Obrigado!!

dahenz

Paulo… PROGRESSO!!! hoje pela manhã o sistema estava conectado… mas um usuário me informou que ontem a noite estava com o broken pipe… não acreditei, foi então que entrei nos logs do servidor e realmente: às 22:15 havia um erro de broken pipe… e outro às 7:24 desta manha…

Mas às 7:45 estava tudo normalizado… não precisei nem reiniciar o tomcat… o que isso significa???

Alguma idéia???

Criado 26 de outubro de 2009
Ultima resposta 9 de nov. de 2009
Respostas 22
Participantes 5