Salas intermitentes do servidor da web do Apache

1

Nosso servidor web SOAP está rodando em PHP no Apache no CentOS e faz uso pesado do MySQL. Há uma grande demanda no servidor - a maioria das solicitações é muito pequena e envolve apenas duas ou três consultas ao MySQL, mas há uma enorme quantidade delas - potencialmente algumas centenas por segundo nos horários de pico. O tráfego de dados com cada solicitação é geralmente menor que 1Kb, geralmente apenas alguns bytes.

O hardware em que esta sendo executado é bastante decente, 18 núcleos com 32 Gb de RAM, e geralmente lida muito bem. O uso da CPU nunca ultrapassa 30%, o consumo físico de RAM nunca é superior a 50%. No entanto, de vez em quando, o servidor parece travar e o Apache fica obstruído. Isso pode durar cerca de um minuto antes de se soltar novamente e o serviço normal ser retomado.

Eu analisei isso com alguma profundidade para ver o que está acontecendo durante as barracas. O Apache está maximizado em suas conexões, praticamente todas elas no estado de "leitura". O uso da CPU cai para praticamente nada, o uso da memória não muda, a rede e o disco IO despencam, então parece que o sistema está completamente ocioso.

Depois de pesquisar muito, fui levado a acreditar que isso poderia ter a ver com algumas configurações de tempo limite - conexões de rede não sendo liberadas com rapidez suficiente e o Apache se esgotando. Isso explicaria por que o Apache retomará a operação normal depois de um tempo, espera que o tempo limite seja esgotado e, em seguida, continua. Fazer um 'netstat -an' suportaria isso, pois vejo muitas conexões em TIME_WAIT. No entanto, reduzi todos os tipos de configurações de tempo limite na configuração do Apache e também com várias configurações de rede no sysctl.conf, mas nada parece resolver o problema.

Não há nada nos logs de erro do Apache. Eu tentei usar o 'ab' para testar o Apache - parece que a paralisação intermitente acontecerá um pouco mais cedo, mas isso é tudo que eu realmente consigo medir. As conexões máximas para o Apache e o MySQL são configuradas para valores altos - conexões concorrentes reais nunca se aproximam, exceto durante a paralisação quando as conexões do Apache excedem.

Eu não tenho certeza do que mais tentar. Alguma idéia ou indicação de coisas que eu possa estar perdendo aqui?

- editar -

Algumas observações extras. Quando a tenda está ocorrendo, noto que o número de conexões no estado ESTABLISHED aumenta consideravelmente, então o número em CLOSE_WAIT ocorre alguns segundos depois.

Além disso, quando a paralisação ocorre, o número de vezes que a fila de escuta de um soquete transbordou e os sockets SYNs para LISTEN ignorados aumentam muito rapidamente. Durante os intervalos entre as barracas, esses números não mudam nada.

Não tenho certeza se esses números são uma causa ou consequência da paralisação. Qualquer ajuda adicional seria muito apreciada.

    
por Mark Williams 05.08.2014 / 20:24

2 respostas

1

Agora resolvi isso, então estou postando a solução caso outras pessoas sintam o mesmo problema.

Esqueci de mencionar que todo o tráfego da Web passa por HTTPS, e essa parece ser a causa. Durante uma paralisação, usei strace e pstack para ver o que um dos processos inativos do Apache estava fazendo. Ele estava preso esperando um mutex para o cache de sessão SSL.

Olhando para a configuração do Apache, notei que o SSLSessionCache estava ativado com um tempo limite de 5 minutos. Desativar esta é a correção.

Meu palpite é que o cache de sessão estava sendo preenchido e, em seguida, o Apache aguardava que as sessões mais antigas atingissem o tempo limite antes de continuar.

    
por 13.08.2014 / 18:24
0

De acordo com o Manual do Apache

Diretiva KeepAliveTimeout

Descrição: Quantidade de tempo que o servidor aguardará solicitações subsequentes em uma conexão persistente Sintaxe: segundos do KeepAliveTimeout Padrão: KeepAliveTimeout 5 Contexto: configuração do servidor, host virtual Status: Core Módulo: core O número de segundos que o Apache aguardará por uma solicitação subsequente antes de fechar a conexão. Uma vez que uma solicitação foi recebida, o valor de tempo limite especificado pela diretiva Timeout se aplica. Definir KeepAliveTimeout para um valor alto pode causar problemas de desempenho em servidores com carga pesada. Quanto maior o tempo limite, mais processos do servidor serão mantidos ocupados aguardando conexões com clientes ociosos. Em um contexto de host virtual baseado em nome, o valor do primeiro host virtual definido (o host padrão) em um conjunto de NameVirtualHost será usado. Os outros valores serão ignorados.

Portanto, no primeiro host (padrão), eu configurei meu KeepAliveTimeout 3, remova qualquer outra referência à diretiva em qualquer outro lugar na configuração e execute novamente o teste de estresse para garantir que seja uma questão de máximo de conexões simultâneas. / p>     

por 06.08.2014 / 02:35