Temos 5 aplicações J2EE rodando num JBoss 4.0.3-SP1, com Java 5.
Estas aplicações estão consumindo cerca de 70% de CPU. O consumo vai aumentando gradativamente até os 70%, até chegar ao limite de memória e o JBoss pára de responder, tendo de ser reiniciado. Isso também foi percebido antes, quando as aplicações rodavam em Java 1.4 e JBoss 3.2.3.
Anteriormente as aplicações estavam normais. Esse aumento de consumo foi percebido e, coincidentemente, perto desse período houve uma atualização nos sistemas.
O administrador de infra-estrutura ACHA que seja por causa de algum lock. Eu acho difícil, mesmo porque não usamos threads diretamente. Enfim.
Minha dúvida é: Qual a melhor forma de eu investigar esse alto consumo de CPU? Existe alguma ferramenta que me auxilie nisso? Ou o velho debug será o jeito?
Se a aplicação usa Oracle pode ser que tenha sessões demais. Precisaria monitorar as VSessions pois elas podem estar acabando com sua memória. Já passei por este problema mas com o tomcat (e o Oracle estava em outra máquina).
Além de profilers que são ótimos mas que dão enorme trabalho para entender os resultados quando a gente não está acostumado com eles, eu gosto muito do glassbox. É uma ferramenta muito útil e acho até indispensável em um ambiente de desenvolvimento web. Não é um profiler mas monitora em tempo real através de AOP sem que você precise alterar uma linha na sua aplicação. E ainda dá dicas em alguns casos de demora na resposta. É a aplicação de AOP mais legal que conheço.
Pode ser devido a um maior consumo de memória. Se tua aplicação passou a usar mais memória e o heap em produção não foi ajustado, pode ocorrer coisas como, por exemplo, ciclos contínuos de full gc devido ao mature space estar muito carregado.
Tem certeza de que todos seus sessions beans (stateless) estão sendo liberados? Isso é bem fácil de verificar: a camada cliente de ejb DEVE sempre chamar explicitamente o método remove (sem isso os objetos ficam presos no server até que role o timeout - e isso pode demorar, dependendo da configuração do seu server app).
Qto a profilers, hmmm, concordo com o Luca: são bem difíceis de entender e nem sempre vc consegue boms resultados com esses caras.
Recentemente tentei o jprofiler, jprobe e uma penca de outros que naum lembro o nome e acabei por fazendo a verificação na unha. Estava com memory leak na minha aplicação e precisei desesperadamente desses caras pra tentar uma solução rápida mas não deu! Só pra aprender a usar esses profilers vc perde um tempão …
1 giga é muita memória ou pouca? Sem conhecer a aplicação ambas respostas estão certas. Tenho em mãos aplicações que 1 giga de memória não dá pra começar.
Louds, o admin disse que as aplicações, antes, não chegavam a 500 megas.
plentz, a atualização suspeita foi feita por mim. Antes, o JBoss precisava ser restartado cerca de 3 ou 4 vezes por semana, por estouro de conexões presas. Investiguei no framework (in-house) que usamos e descobri falhas nele. Acabei atualizando esses pontos e adicionei um HttpSessionListener para matar uma conexão que ficava presa na sessão, por um motivo de mau desenho do framework. Enfim, foi como consegui resolver. Atualizamos 25 aplicações e apenas 5 delas que estão numa mesma instância é que deram problemas.
agodinhost, realmente não chamamos remove() para os ESSB. Mas acho que isso não é o problema, pois antes não tinha esse alto consumo. Aliás, o remove não é um metodo de callback do container? Creio que não deveria ser invocado por que usa o ESSB.
Bom, para adiantar alguma coisa. Descobri que um maldito empacotou o j2ee.jar e o classes12.jar (do Oracle) dentro de um dos EARs. Vou tirar e colocar em produção e ver o que rola.
Stage Time B Sent B Recv Client VHost Request
S 115880205 16384 79 200.25.220.166 www.xxx.com.br POST/cge/SEControl?resource=/respostaPagtosData.jspHTTP/1.0
S 115634097 0 0 200.25.220.166 www.xxx.com.br GET/cge/SEControl?resource=/consultaQtdeRecebidaPubl.jspHTTP/1.0
S 112856065 131072 101 200.142.81.222 www.xxx.com.br POST/cge/SEControl?resource=/respostaPagtosData.jspHTTP/1.0
S 105647934 0 0 200.142.81.222 www.xxx.com.br GET/cge/SEControl?resource=/detalheVirtual.jsp&nroSolicitacao=110073&valor=0&juros=0&codProduto=13723001&edicao=12&rnd=98456HTTP/1.0
S 92560284 0 0 200.142.81.222 www.xxx.com.br GET/cge/SEControl?resource=/index.jspHTTP/1.0
Dá pra ver que uma das aplicações é que tem muitas requisições com tempos longos demais.
Bom, primeira coisa, você consegue verificar se seu HttpSessionListener está realmente matando a conexão? Depois disso, chegou a ver se ele não está “empacando” ao tentar fechar alguma conexão? O problema não deve estar justamente no seu HttpSessionListener?
Então, vou tentar verificar ai também. Existe zilhões de possibilidades.
O listener funcionou bem nos testes e na implantação, pois não tínhamos mais que reiniciar o Jboss por causa das conexões presas. Isso passou a ocorrer a cada 7 ou 10 dias.
A atualização pode ser mera coincidência também.
Avaliar isso será bem difícil. Creio que terei que atacar uns pontos e usar teste de stress na máquina de testes para ver se simulo a utilização da produção.
Vou repetir um dos meus conselhos: se a base de dados for Oracle, não deixe de incluir o DBA na monitoração dos parâmetros dele. Pode ajudar muito a descobrir porque há necessidade de reiniciar o JBoss tão freqüentemente.
O caso de conexões presas é antigo e apanhamos muito com isso já. Todos foram envolvidos e o problema era mesmo da aplicação. Tanto é que eu resolvi 99%. Apesar de que ainda existe alguma conexão presa, mas isso não incomoda tanto eles.
Mas este problema não parece relacionado com o nosso problema atual.
Estou com um problema parecido na minha aplicação e não consigo identificar a causa. Tenho uma aplicação web que acessa intensivamente o banco de dados, localizado remotamente (MS SQL Server).
Acontece que, passado algum tempo, a aplicação simplesmente pára de responder e tenho que reiniciar o servidor, acontece tanto no JBoss quanto no Glassfish.
Isso já estava acontecendo antes, mas acontecia com menos tempo e era porque eu não havia fechado todas as conexões. Agora todas as conexões estão fechadas, pelo menos isso que mostra a tela de administração do Glassfish, e o problema continua acontecendo, apesar de demorar mais um pouco para ocorrer.