Diagnosticando a causa da alta contagem de “Servidores Ocupados” do Apache

1

Pedimos desculpas antecipadamente por uma questão levemente prolixa.

Oferecemos hospedagem e gerenciamento de aplicativos de um aplicativo da Web J2EE. A pilha de tecnologia é o CentOS 5.9 de 64 bits, o Apache 2.2.17, o Tomcat 5, o JBoss 4.2.2. O servidor (virtual) tem 6 GB de RAM. Normalmente, vemos cerca de 2500 usuários simultâneos durante o horário comercial e, como regra, o ambiente é executado corretamente (chegamos a ter 3300 usuários simultâneos sem nenhum problema de desempenho). Recentemente tivemos algumas interrupções breves e não temos certeza sobre a causa raiz. As interrupções duram apenas alguns minutos - tempo suficiente para obter o e-mail de alerta do software de monitoramento, verificar se o aplicativo não está disponível, abrir um terminal no servidor e reiniciar um serviço - cerca de 2 a 3 minutos.

Algumas informações em relação às interrupções:

  • Todos os serviços ainda estavam em execução - nada havia sido danificado e não foram gerados despejos de heap
  • Nenhuma mensagem de erro apareceu no navegador
  • Ao tentar acessar o site, nada seria carregado no navegador, e parecia passar uma eternidade pensando - como se estivesse "girando as rodas"
  • Inicialmente reiniciando o acesso restaurado do Apache; mas após a quarta interrupção no espaço de 2 horas, reiniciamos o JBoss. Isso pareceu resolver o problema.
  • Durante as interrupções, a simultaneidade foi bastante baixa - bem abaixo da média durante o horário comercial

Analisamos arquivos de log, relatórios de monitoramento, logs de GC, etc. O que podemos dizer com certeza é que, no momento das interrupções, o software de monitoramento relatava que havia pilhas de servidores ocupados do Apache. Não tenho certeza do que é um Servidor Ocupado, mas no momento de uma interrupção esse valor subiu para entre 150 e 200. O valor médio para Servidores Ocupados é de aproximadamente 5, raramente ultrapassando 10. Também podemos ver os registros do GC que parecia haver um problema de memória no momento das interrupções, por exemplo:

4967.376: [Full GC [PSYoungGen: 17576K->0K(656384K)] [PSOldGen: 3131794K->628760K(3145728K)] 3149370K->628760K(3802112K) [PSPermGen: 157485K->157485K(315008K)], 2.6067200 secs]

As opções da JVM são:

JAVA_OPTIONS="${JAVA_OPTIONS} -Xms4096m -Xmx4096m -XX:NewRatio=3 -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=4"
JAVA_OPTIONS="${JAVA_OPTIONS} -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -XX:+DisableExplicitGC -XX:+UseLWPSynchronization"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+PrintClassHistogram -XX:+HeapDumpOnOutOfMemoryError -Xloggc:sabagc.log -XX:+PrintGCDetails"

O que achamos que aconteceu é que o Permgen ficou sem espaço, o que faz com que o Tomcat pare de aceitar pedidos (do Apache via mod_jk). Isso faz com que o Apache inicie solicitações de enfileiramento, portanto, o alto número de servidores ocupados. Reiniciar o Apache foi uma correção de curto prazo porque não resolveu o problema de memória. A memória foi liberada quando reiniciamos o JBoss.

Com base nas informações disponíveis, isso parece plausível? E é a solução para aumentar a memória para XX: PermSize e XX: MaxPermSize?

    
por MrGordonz 14.08.2013 / 10:03

0 respostas