Escalabilidade - JSF, Hibernate, Spring e Tomcat 6

10 respostas
DirceuSobrinho

Olá, pessoal!

estou com probleminhas ao colocar minha aplicacao em ambiente de produção

e gostaria tb de algumas dicas para deixar minha aplicação mais escalavel.

1°. O problema: qdo poucos usuários estão utilizando o sistema desenvolvido simultaneamente, o acesso a banco de dados cai! como assim: as páginas que acessam o BD deixam de enviar resposta e aguardando-as eternamente, no entanto, as que não acessam BD continuam funcionando normalmente!

Reinicio o Tomcat e tudo volta a funcionar normalmente!

O que pode estar acontecendo?

OBS.: A grande maioria dos relacionamentos das entidades estão com Fetch.EAGER, pois dispara algumas excecoes de Lazy Initialization Exception mesmo utilizando o OpenSessionInView, e com o EAGER eu fujo deste problema!

ATT. Dirceu

10 Respostas

DirceuSobrinho

VENDO O LOG DO SERVIDOR WEB:

- Creating instance of br.com.id5.legba.core.seguranca.AuthenticationController
- Creating instance of br.com.id5.legba.classificados.controlador.backingBeans.AnuncioBean
- Creating instance of br.com.id5.legba.classificados.controlador.backingBeans.AnuncioBean
- Closing org.springframework.web.context.support.XmlWebApplicationContext@164cbde: display name [Root WebApplicationContext]; startup date [Wed Jul 09 03:15:28 GMT-03:00 2008]; root of context hierarchy
- Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ad0839: defining beans [pedidoDao,pagSegDao,pedidoStatusDao,coreName,usuarioDao,usuarioGerenciador,enderecoDao,grupoDao,grupoGerenciador,contatoDao,moduloDao,moduloGerenciador,regraDao,regraGerenciador,moduloManagerBean,menuTreeBean,imagemDAO,administradorDao,anuncianteUserDao,visitanteCadastradoDao,administradorBean,anuncianteBean,visitanteBean,anuncioDao,anuncioVeiculoDao,anuncioImovelDao,anuncioEmpregoDao,anuncioGenericoDao,anuncioAdultoDao,pacoteDao,pacoteEspecificacaoDao,adultoDao,carroDao,empregoDao,fabricanteDAO,genericoDao,imovelDao,modeloDAO,motoDao,opcionalVeiculoDAO,opcionalImovelDAO,veiculoDao,fabricanteDao,secaoDao,categoriaDao,perguntaDao,dataSource,sessionFactory,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager,projectHome,acegiFilterChainProxy,httpSessionContextIntegrationFilter,securityRequestFilter,exceptionTranslationFilter,filterSecurityInterceptor,methodSecurityInterceptor,authenticationManager,daoAuthenticationProvider,userDetailsService]; root of factory hierarchy
- Closing Hibernate SessionFactory
- closing
- Destroy instance of org.apache.myfaces.config.RuntimeConfig
- Destroy instance of [Ljava.lang.String;
- Destroy instance of java.io.File
- Destroy instance of java.lang.String

O QUE PODE ESTA CAUSANDO ISSO:

[i]Closing org.springframework.web.context.support.XmlWebApplicationContext@164cbde: display name [Root WebApplicationContext]; startup date [Wed Jul 09 03:15:28 GMT-03:00 2008]; root of context hierarchy
- Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ad0839: defining beans [pedidoDao,pagSegDao,pedidoStatusDao,coreName,usuarioDao,usuarioGerenciador,enderecoDao,grupoDao,grupoGerenciador,contatoDao,moduloDao,moduloGerenciador,regraDao,regraGerenciador,moduloManagerBean,menuTreeBean,imagemDAO,administradorDao,anuncianteUserDao,visitanteCadastradoDao,administradorBean,anuncianteBean,visitanteBean,anuncioDao,anuncioVeiculoDao,anuncioImovelDao,anuncioEmpregoDao,anuncioGenericoDao,anuncioAdultoDao,pacoteDao,pacoteEspecificacaoDao,adultoDao,carroDao,empregoDao,fabricanteDAO,genericoDao,imovelDao,modeloDAO,motoDao,opcionalVeiculoDAO,opcionalImovelDAO,veiculoDao,fabricanteDao,secaoDao,categoriaDao,perguntaDao,dataSource,sessionFactory,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager,projectHome,acegiFilterChainProxy,httpSessionContextIntegrationFilter,securityRequestFilter,exceptionTranslationFilter,filterSecurityInterceptor,methodSecurityInterceptor,authenticationManager,daoAuthenticationProvider,userDetailsService]; root of factory hierarchy
- Closing Hibernate SessionFactory[/i]
U

vc ta usando um pool de conexão ? que problema estranho…

DirceuSobrinho

Não estou nao

o hibernate.cfg esta configurado da seguinte forma:

<session-factory>
    
         <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        <property name="hibernate.connection.password">123456</property>
        <property name="hibernate.connection.url">jdbc:jtds:sqlserver://192.168.1.1:1433/mercado24horas</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
    	<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>
		<property name="current_session_context_class">thread</property>
		<property name="hibernate.cache.use_query_cache">true</property>
		<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		<property name="hibernate.max_fetch_depth">0</property>

Crio um pool?

D

Crie um pool e coloque os relacionamentos em Lazy, pq da forma q está fazendo, não há servidor que resista.

DirceuSobrinho

Adicionei no hibernate.cfg.xml

<property name="hibernate.dbcp.maxActive">8</property>
		<property name="hibernate.dbcp.maxIdle">8</property>
		<property name="hibernate.dbcp.maxWait">-1</property>
		<property name="hibernate.dbcp.whenExhaustedAction">1</property>
		<property name="hibernate.dbcp.testOnBorrow">true</property>
		<property name="hibernate.dbcp.testOnReturn">false</property>

Isso basta para criar um pool?

subi a aplicacao com essas alteracoes e vou aguardar qto tempo dura sem cair…

e aos vou tentar eliminar o Fetch.EAGER, subsitituindo por LAZY


Mais sugestões, sintam-se a vontade =)

Att. Dirceu

Rubem_Azenha

Putz, posta aí como ta o código do seu Filter pra funcionar o esquema do Open Session In View.

DirceuSobrinho

Aqui está!

import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.CleanupFailureDataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;

/**
 * @author frank
 * this class inherits the class OpenSessionInViewFilter to
 * set the session to "AUTO" instead of "NEVER"
 */

public class FlushingSpringSessionInViewFilter extends OpenSessionInViewFilter { 

    public FlushingSpringSessionInViewFilter() { 
    } 

    protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { 
       Session session = SessionFactoryUtils.getSession(sessionFactory, true); 
       session.setFlushMode(FlushMode.AUTO); 
       return session; 
   } 
    
    protected void closeSession(Session session, SessionFactory sessionFactory) throws CleanupFailureDataAccessException { 
        if (session != null && session.isOpen() && session.isConnected()) { 
            try { 
                session.flush(); 
            } catch (HibernateException e) { 
                throw new CleanupFailureDataAccessException("Failed to flush session before close: " + e.getMessage(), e); 
            } 
        } 
        super.closeSession(session, sessionFactory); 
    } 
}

Em algumas paginas, o openSessionInView está funcioando como esperado, nas que so tem <h:outputText>
ja nas que possuem <h:inputText> dispara a famosa: Lazy Initialization Exception

Rafael.bnc

Este problema também acontece comigo. Alguém conseguiu resolver?
O que eu faço é sempre que eu tenho que acessar uma coleção de um objeto eu tenho que dar um load nele pora evitar a Lazy Initialization Exception.

DirceuSobrinho

rafaelbnc:
Este problema também acontece comigo. Alguém conseguiu resolver?
O que eu faço é sempre que eu tenho que acessar uma coleção de um objeto eu tenho que dar um load nele pora evitar a Lazy Initialization Exception.

Oi Rafael, com filtro OpenSessionInView, não precisei mais dar um load para evitar a LazyInitialization, no entanto, para que em requisições ajax, foi necessário alterar o filtro, ai peguei na net esse filtro que tá funcioando blz:

import java.io.IOException;
import java.sql.Connection;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;

/**
 * @author Chris DeBracy
 * 
 */
public class HibernateLongSessionFilter extends OpenSessionInViewFilter {

	/**
	 * Logger.
	 */
	private static Log log = LogFactory.getLog("HibernateLongSessionFilter");

	public static final String SESSION_KEY = "hibernateSession";

	public static final String CONNECTION_KEY = "hibernateConnection";

	protected void doFilterInternal(HttpServletRequest request,
			HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		SessionFactory sessionFactory = lookupSessionFactory(request);

		/*
		 * Retrieve the session or instantiate it.
		 */
		Session session = (Session) request.getAttribute(SESSION_KEY);
		Connection connection = (Connection) request
				.getAttribute(CONNECTION_KEY);
		if (session == null) {
			session = getSession(sessionFactory);
			request.setAttribute(SESSION_KEY, session);

		} else {

			connection = (Connection) request.getAttribute(CONNECTION_KEY);
			try {
				session.reconnect(connection);
			} catch (RuntimeException e) {
				log.info("Already connected");
				log.info(e);
			}
		}

		try {
			filterChain.doFilter(request, response);
		}

		finally {

			try {
				connection = session.disconnect();
				request.setAttribute(CONNECTION_KEY, connection);
			} catch (RuntimeException ex) {
				logger
						.error(
								"Unexpected exception on closing Hibernate Session",
								ex);
			}
		}
	}
}

Espero que te ajude!!!

Att. Dirceu

Rafael.bnc

Cara vai ajudar muito sim, eu já tinha desistido desse problema mas acabei encontrando este teu post.
Eu não tinha percebido que o problema da LazyInitialization era por causa dos Ajax requests (RichFaces).
O problema é que eu não utilizo o Spring, eu implementei o meu próprio filtro, mas segue o mesmo estilo. MUITO obrigado me ajudou muito, pois como te disse eu sempre tinha que fazer um Load nos objetos o que acabava deixando o código um pouco confuso.

Criado 10 de julho de 2008
Ultima resposta 18 de set. de 2008
Respostas 10
Participantes 5