Pool de conexão Glassfish e/ou Tomcat - como fazer?

15 respostas
jomello_br

Olá amigos, eu venho pesquisando (e muito) sobre pool de conexão.
Bom desenvolvi um sistema que utiliza JSF+PRIMEFACES-2.2.1+HIBERNATE.3.2.5+GLASSFISH 3.1 e/ou Tomcat 7.

Porque o Glassfish e/ou Tomcat?
Simples … quero poder rodar minha aplicação nos principais servidores web (claro que quero os outros tambem, mas vamos nos ater aos mais utilizados (ou não))

Pois bem, partindo pelo Netbeans basta eu criar as configurações direto por ele que ele proprio se encarrega de criar/configurar automaticamente.

Agora vamos ao meu problema, e de ante mão já falo, quis apenas testar outras configurações para ver como funcionava, portanto posso dizer que a minha configuração não funciona ok :slight_smile:

Primeiro o Tomcat 7, toda e qualquer configuração que fiz me gera o tal perm gen, portanto nem posso dizer o que fiz de errado.

Segundo, vou colocar aqui os meus arquivos para analise, mas vamos lá pessoal, vamos criar um verdadeiro e real tutorial para todos ok (essa é a minha intensão maior ok amigos).

Segue abaixo a minha configuração que não da nenhum erro, somente não grava no banco ok. (lembrem essa minha configuração é fora do “padrão” ok)

PERSISTENCE.XML

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="br.finan.0PU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>salao</jta-data-source>
    
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
      <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />
    </properties>
  </persistence-unit>
</persistence>

glassfish-resources.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool allow-non-component-callers="false" 
    associate-with-thread="false" 
    connection-creation-retry-attempts="0" 
    connection-creation-retry-interval-in-seconds="10" 
    connection-leak-reclaim="false" 
    connection-leak-timeout-in-seconds="0" 
   [b] connection-validation-method="custom-validation" [/b]
    datasource-classname="org.postgresql.ds.PGSimpleDataSource" 
    fail-all-connections="false" 
    idle-timeout-in-seconds="300" 
    is-connection-validation-required="false" 
    is-isolation-level-guaranteed="true" 
    lazy-connection-association="false" 
    lazy-connection-enlistment="false" 
    match-connections="false" 
    max-connection-usage-count="0" 
    max-pool-size="32" 
    max-wait-time-in-millis="60000" 
    name="post-gre-sql_salao_salaoPool" 
    non-transactional-connections="false" 
    pool-resize-quantity="2" 
   [b] res-type="java.sql.ConnectionPoolDataSource" [/b]
    statement-timeout-in-seconds="-1" 
    steady-pool-size="8" 
    validate-atmost-once-period-in-seconds="0" 
    wrap-jdbc-objects="false">
        
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="5432"/>
        <property name="databaseName" value="salao"/>
        <property name="User" value="salao"/>
        <property name="Password" value="salao"/>
        <property name="URL" value="jdbc:postgresql://localhost:5432/salao"/>
        <property name="driverClass" value="org.postgresql.Driver"/>
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" jndi-name="salao" object-type="user" pool-name="post-gre-sql_salao_salaoPool"/>
</resources>

Negritei as duas linhas principais para ver o que acontece, mas é ai que o bicho pega.

Claro que achamos varios tutoriais / ajudas, mas vamos concordar que para quem não conheçe é quase impossivel entender/aprender??

Logico que muitos que já sabem vão falar que bobagem e outros que já resolveram os seus problemas seguer vão dar bola, mas olham para atrás e verão que ontem voces não sabiam isso.

Portanto no intuito de “me ajudar” e tambem “ajudar” os outros, vamos tentar criar um guia definitivo de como criar um pool de conexão para os servidores principais que acho sejam Tomcat,Glassfish,Jboss e WebLogic.

Abraços e fiquem com Deus

Jomello

15 Respostas

FernandoFranzini

Eu acho que vc complicou muito a pergunta de modo que eu não entendi qual é sou problema.

  1. A especificação JEE diz que os servidores web e ejb container devem fornecer provedores de pool DataSource, mas não diz como, deixando cada fazer de sua forma especifica. Sua aplicação fica livre e independente para ser usando em qualquer provedor. Eu ja portei muitos war para vários deles.

  2. Não exite nada de errado com o “perm gen”. Isso só quer dizer que acabou o espaço de memoria especifico dentro do HEAP. Quando vc vai fazer deploy para o ambiente de produção de uma solução, vc ja deve ter uma media de gastos de um sessão aberta + media de usuários por minutos = configurações dos parâmetros do HEAP da JVM. Muito normal de se fazer…

  3. Cada site do provedor ja tem um tutorial pronto, vc acessa eles quando precisar…

luxu

Se possível um exemplo Fernando pois tb colocarei meu sistema para produção e estou com muitas dúvidas a respeito disso…

FernandoFranzini

Não tem como passar um exemplo…cada caso é um caso…
Vc na verdade precisa entender como funciona as areas da JVM e assim implementar a solução sabendo de onde vc faz os maiores gastos.
Segue os links…
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html



http://codare.net/2007/01/11/java-solucionando-o-erro-de-permgen-space/
Na revista mundo java (MundoJ) edição 35 tem uns dos melhores artigos sobre isso que eu ja li.
e por ai vai…

jomello_br

Obrigado Fernando pela super ajuda, isso ajuda a compreender um pouco as coisas, mas não resolve as coisas :slight_smile:

Bom vamos lá, claro que eu sei o que gera o perm gem, mas fica dificil para nos pessoas normais o porque?

E ai é complicado dizer o que gerou essa falta de recursos, porque cada caso é um caso e procurar o porque de dentro do IDE pode não resolver, até porque o proprio IDE pode esta concorrendo e gastando recursos da JVM, então é um trabalho de formiguinha para achar o que esta gerando o problema.

Mas seguindo os seus link´s da uma boa ajuda para cada um achar o que a sua aplicação esta gerando o problema.

Quanto ao pool de conexão, bom a forma mais simples e facil de resolver o problema é usar RESOURCE_LOCAL se quiser ter controle sobre as transações locais ou usar JTA deixando o servidor cuidar das suas transações.

E ai recomeça as questões, mas “como” o meu servidor vai saber quando começar / terminar uma transação?

Ta e como eu sei como controlar uma transação que eu tenha que dar insert em varias tabelas e a transação só é valida se todas as tabelas forem true?

Outra… como eu controle isso via Hibernate e como controle isso via JDBC??

Calma, estou querendo é criar algo para que todos possam usar.

Responder todas essas perguntas é de certa forma facil e rapido, mas temos que não somente entender, temos que compreender e sou sincero não compreendo nadica de nada :slight_smile:

Estou indo atras do Spring Security que até onde li parece que resolve tudo isso sozinho, mas fora isso vou tentar achar as melhores soluções para persistencia e para JDBC ok amigos.

Abraços e fiquem com Deus

Jomello

FernandoFranzini

Eu te entendo amigo e é realmente complicado assim…
Por isso que hoje no mercado uns do profissional mais bem pagos são os “Arquitetos” que detém experiência, conhecimento e credenciais para resolver cada questão sua mencionada e muitas muitas outras que vc nem chegou a pensar…kkkkk É oque eu tenho tentando aprender e fazer nos últimos 12 anos…
Eu me coloco a disposição para te ajudar no quer for possível…

jomello_br

Opa, valeu Fernando.

Deixa eu terminar de implementar o Spring Security que pelo que vi aparentemente nao vou precisar “saber” qual vai ser o meu servidor.

E tenho certeza que vou gerar muito mais perguntas do que respostas. :slight_smile:

Abraços e fique com Deus

Jomello

FernandoFranzini

luxu:
FernandoFranzini:

2) Não exite nada de errado com o “perm gen”. Isso só quer dizer que acabou o espaço de memoria especifico dentro do HEAP. Quando vc vai fazer deploy para o ambiente de produção de uma solução, vc ja deve ter uma media de gastos de um sessão aberta + media de usuários por minutos = configurações dos parâmetros do HEAP da JVM. Muito normal de se fazer…

Se possível um exemplo Fernando pois tb colocarei meu sistema para produção e estou com muitas dúvidas a respeito disso…

Bom segue ai um exemplo rápido sem muito aprofundamento:
*) Uma aplicação web bancaria projetada por mim que hoje conta com 10 mil usuários cadastrados, apresentando uma media de 800 sessões por minuto simultâneo.
*) Cada sessão representa um usuário logado que pode fazer uma serie de operações financeiras que resulta em gasto médio de memoria X (contando gastos com a sua sessão aberta).
*) Nos dias/semanas de picos (devidamente monitorado) temos uma variação de 800 a 1200 dando uma media geral de 1 mil pessoa mensal. Essa é minha demanda hoje.
*) A aplicação tem um valor médio com gastos de memoria Y relacionado com recursos estáticos (valores, parâmetros, caches etc…) compartilhado por todos os usuários do sistema.
*) De posse destas informações = quanto se gasta com 1 sessão + quantas sessões eu preciso manter + recursos estáticos = VALOR_DE_MEMORIA_NECESSÁRIO.
*) A aplicação esta na web e a qualquer momento pode acontecer de termos um numero maior de acessos simultâneos do que o esperado (media geral). Por isso nos adicionamos 25% de memoria a mais para ter essa margem de acesso.
*) O Hot deploy dos container Java normalmente acabam detonando o HEAP quando atualizam a versão da aplicação (é aqui que o perm gem vai pro vinagre kkkk) e por isso definimos + uns 20% de memoria a mais para suportar as atualização
*) Meu servidor linux com o tomcatzinho é então montado com memoria X que reflete o valor =
VALOR_DE_MEMORIA_NECESSÁRIO + 25% para as possíveis sessões extras + 20% gastos no hot deploy = VALOR DE MEMORIA DO JAVA DA JVM.
*) Resultado final…a aplicação fica no ar, 800 sessões por minutos, gastando 60 % da memoria, que é remanejada a cada execução do GC() a empresa feliz da vida e eu dormindo super tranquilo nas minhas noites de sono hehehehehheee…
Vc pode apurar melhor e configurar cada região da memoria em especifico, mas configurando HEAP min e max geral já vai resolver 90 % dos problemas.

Outra questão é sua aplicação foi implementada com boas praticas de memoria? ela realmente ta gastando o minimo? existem meios de vc otimizar? aonde?
E assim minha aplicação esta no ar funcionando redondo. A medida de acontece o cadastro de novos usuários, pode ser que venhamos a ter um aumentar o numero de sessões simultâneas…ou não. Eu e minha equipe vamos monitorando o sistema para administrar isso, antecipando todas as necessidades…escalando verticalmente e/ou horizontalmente a solução.
E por ai vai…

jomello_br

Muita hora nessa calma he he he :slight_smile:

Ta tudo isso que vc falou eu até sei, mas como sou da velha guarda não sei é “como” implementar tudo isso no JAVA :slight_smile:

Mas vamos lá.

Voce utiliza algum framework alem do hibernate?

Porque eu tenho perm gen com o Tomcat e não com o Glassfish, sendo que somente redireciono?

Outra questão é sua aplicação foi implementada com boas praticas de memoria?

Em termos leigo, eu acho que sim, faço uma unica conexão com o banco e só libero os statement´s, procuro sempre que possivel deixar o menos possivel na sessão (http)

Tudo que não estou utilizando no momento procuro “limpar” da memoria.

O problema maior de usar framework´s (na minha modesta opinião) é que a gente não sabe o que rola por trás e somente confia, ai quando da pau ficamos doidos :slight_smile:

Abraços

Jomello

FernandoFranzini
  1. Essa aplicação esta baseando em JSF+Spring+JPA(hibernate como provider)+Tomcat+iReport+SQLServer
  2. Hoje na aplicação eu tenho um plano de otimização ja implementado e tenho pontos que posso otimizar ainda mais mas ainda não fiz pq meus recursos verticais estão de sobras.
    3)Existem muito muitos tópicos praticas de otimização (que não caberia aqui dizer) que poucos sabem.
  1. isso que vc falou realmente infere muito…usar coisa dos outros que vc não sabe se foi bem feitas…mas bons frameworks normalmente não são o gargalo…o problema ainda é arquitetura…

Eu não tenho como te ajudar no seu problema pq não sei oq vc fez para estourar memoria…eu teria que ver o código, depurar e verificar

jomello_br

The best esse seu tutorial Práticas de Aplicativos Web.

A boa noticia é que eu sigo a grande maioria do que é dito, o que fica faltando é exatamente aquilo que compreendo mas não entendo :slight_smile:

Bom vou digerir toda essa informação para então poder tirar as minhas duvidas e tentar ajudar os outros amigos :slight_smile:

Abraços e fique com Deus

Jomello

jomello_br

Olá meu povo, tudo a riba?? :slight_smile:

Bom finalmente consegui resolver as questões de como criar pool de conexão para vários servidores.

Primeiro que criar uma aplicação prevendo vários servidores é complicado, mas não impossivel.

Configuração do Tomcat 7, achei aqui mesmo :slight_smile:
http://www.guj.com.br/java/211344-jndi-datasource

E como a partir da versão 6 o Tomcat não tem mais o admin, graças ao nosso amigo Fernando tem o
PROBE: http://www.lambdaprobe.org/d/index.htm

Configuração Glassfish 3.x
http://rafaelomarques.wordpress.com/2011/01/31/configurando-pool-de-conexoes-com-mysql-e-glassfish-v3/

Configuração WebLogic
http://mmaiacupofcoffee.blogspot.com/search/label/Administra%C3%A7%C3%A3o%20Weblogic

Configuração JBoss
http://docs.jboss.org/jbossweb/3.0.x/jndi-datasource-examples-howto.html

Agora para entender e saber o que configurar usando Hibernate, tem essa leitura obrigatória
http://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/session-configuration.html

Valeu Fernando pela sua inestimavel ajuda e seus links que me ajudaram a compreender todo o conceito de transações dentro do Java.

Abraços a todos e espero ter ajudado de alguma forma, fiquem com Deus

Jomello

OBS: Faltou falar um trem, estou colocando o meu emf dentro da minha session (http).

emf = Persistence.createEntityManagerFactory(“financeiroPU”);
session.setAttribute(“emf”,emf);

Mas ai fico com a sensação de ter algo errado, por que?

Porque, se eu simplesmente desligar a minha estação a minha conexão vai ficar “presa” até dar o timeout (eu acho), até onde entendi o createEntityManagerFactory é o que faz a conexão com o pool e se ficar dando createEntityManagerFactory toda vez que eu precisar vou ficar gastando conexões a toa sem contar que a minha aplicação vai ficar uma carroça :-).

Portanto fiz uma continha basica: numero_usuarios = numero_conexoes + 1/4, isto esta certo?

FernandoFranzini

Ola jomello_br
Vamos la.

*) Sobre o EntityManagerFactory:
1)A sessão corresponde ao lugar aonde temos que guardar as coisas pertencentes ao usuário no qual ele vai precisar entre as varias invocações(http request) durante a utilização do sistema…e o objeto EntityManagerFactory não é um deles pq ele é compartilhado entre todos os usuários. A forma correta de fazer isso é usando SINGLETON. Então crie um classe JPAUtil e coloque o EntityManagerFactory como static, podendo ser usado em qualquer sessão.

  1. EntityManagerFactory deve ser criado apenas 1 vez e compartilhado por todos os usuários…se vc não esta usando nenhum framework que faça isso para vc (Spring, EJB, etc…) vc pode fazer na unha criando um serlvlet context listener que abre apenas 1 EntityManagerFactory no deploy e destroi ele no undeploy.

*) Numero de conexões no Pool.
Eu não entendi seu comentário sobre a conexão mas o objetivo da abordagem do pool é reduzir o numero de conexões uma vez que elas são compartilhadas entre os usuários não simultâneos…por isso a media fica bem mais baixa…mais ou menos UMA CONEXÃO POR 10 usuários ou pouco menos.

FernandoFranzini

jomello_br:
Olá meu povo, tudo a riba?? :slight_smile:

Configuração do Tomcat 7, achei aqui mesmo :slight_smile:
http://www.guj.com.br/java/211344-jndi-datasource

Configuração Glassfish 3.x
http://rafaelomarques.wordpress.com/2011/01/31/configurando-pool-de-conexoes-com-mysql-e-glassfish-v3/

Configuração WebLogic
http://mmaiacupofcoffee.blogspot.com/search/label/Administra%C3%A7%C3%A3o%20Weblogic

Configuração JBoss
http://docs.jboss.org/jbossweb/3.0.x/jndi-datasource-examples-howto.html

Só faltou o Jetty e Geronimo…Vc coloca ai o link?

jomello_br

Opa e ai Fernando tudo bem contigo??? :slight_smile:

Jetty:
http://docs.codehaus.org/display/JETTY/DataSource+Examples#DataSourceExamples-PoolingDataSources

Geronimo:
https://cwiki.apache.org/GMOxDOC22/monitoring-thread-pools.html

Agora o proximo desafio é o Spring :smiley:

Abraços e fique com Deus

OBS: Esses dois eu nem cheguei perto deles he he he :slight_smile:

FernandoFranzini

Antes de qualquer coisa…adquira e leia o - Spring in Action!
Bons estudos 8)

Criado 1 de julho de 2011
Ultima resposta 12 de jul. de 2011
Respostas 15
Participantes 3