debugging JBoss 100% de uso da CPU

1

Estamos usando o JBoss para executar dois dos nossos WARs. Um é o nosso aplicativo da web, o outro é o nosso serviço da web. O aplicativo da Web acessa um banco de dados em outra máquina e faz solicitações ao serviço da web. O serviço da Web faz solicitações JMS para outras máquinas, agrega os dados e os retorna.

No nosso maior cliente, cerca de uma vez por mês, o processo Java do JBoss leva 100% de todos os processadores. A máquina rodando o JBoss possui 8 CPUs. Nosso aplicativo da Web ainda está acessível durante esse período. No entanto, as páginas demoram cerca de 3 minutos para serem carregadas. Reiniciar o JBoss restaura tudo ao normal.

A máquina do banco de dados e todas as outras máquinas estão bem, somente a máquina rodando o JBoss é afetada. O uso da memória é normal. A utilização da rede é normal. Não há mensagens de erro suspeitas nos logs do JBoss.

Eu configurei um ambiente de teste o mais próximo possível do ambiente de produção do cliente e fiz testes de carga com até 2x o número de usuários simultâneos. Eu não consegui meu ambiente de teste para replicar o problema.

Para onde vamos a partir daqui? Como podemos diminuir o problema?

Atualmente, o único plano que temos é esperar até que o problema ocorra na produção por conta própria, depois fazer alguma depuração para determinar a causa. Até agora, as pessoas apenas reiniciaram o JBoss quando o problema ocorreu para minimizar o tempo de inatividade. Na próxima vez que isso acontecer, eles terão um desenvolvedor para dar uma olhada. A questão é, da próxima vez que acontecer, o que pode ser feito para determinar a causa?

Poderíamos configurar uma instância separada do JBoss na mesma caixa e instalar o aplicativo da web separadamente do serviço da web. Desta forma, quando o problema ocorrer, saberemos qual WAR tem o problema (assumindo que é o nosso código). Isso não diminui muito, muito embora.

Devo ativar o JMX remoto? Dessa forma, da próxima vez que ocorrer o problema, posso conectar-me ao VisualVM e ver quais threads estão usando a CPU e o que diabos eles estão fazendo. No entanto, existe uma desvantagem significativa ao ativar o JMX remoto em um ambiente de produção?

Existe outra maneira de ver quais segmentos estão comendo a CPU e obter um stacktrace para ver o que eles estão fazendo?

Alguma outra ideia?

Obrigado!

    
por Nate 13.03.2010 / 00:21

2 respostas

2

Você pode enviar um sinal SIGQUIT para a JVM em execução para que os rastreamentos de pilha de cada encadeamento sejam impressos no stdout. Isso não mata o processo, embora eu ache que ele coloque todos os threads em suspensão enquanto os rastreamentos de pilha estão sendo impressos.

Em seguida, correlacione os IDs de encadeamento listados com seu método preferido de ver a utilização da CPU em termos de threads. prstat -L para Solaris, top -H para Linux. Observe que os vestígios de tid nos rastreamentos de pilha java são impressos em hexadecimal; você provavelmente terá que converter para decimal ao comparar com a saída top ou prstat.

    
por 15.03.2010 / 20:31
1

Eu faço um dump de thread. No entanto, em meus sistemas de produção, isso não pode ser feito a menos que a JVM seja iniciada com determinados parâmetros que nunca seriam ativados na produção. Nesse caso, eu uso o jboss.system do console JMX: type = ServerInfo mbean para fazer o dump do encadeamento (listThreadDump ()).

A saída do dump de thread não faz sentido para mim quando não escrevo o código. Mas a pessoa que escreveu o código pode ser capaz de entendê-lo. Nesses casos em que os dumps de encadeamento não ajudam, prefiro usar " strace -fp <PID of JBoss' java process> -o outfile.txt " para ter outra visão do que está acontecendo em um nível de chamada de sistema. É um pouco como beber de uma mangueira de incêndio, mas às vezes ajuda.

    
por 15.03.2010 / 23:46