Apache MaxClients atingido, servidor sem resposta, mesmo fora do pico

3

Temos um servidor Apache que quase diariamente não responde. Ao verificar / status do servidor (mod_status), podemos ver que temos 60 processos filhos que estão todos em um estado "W" (Resposta de Envio).

  1. Se executarmos service httpd restart , tudo volta ao normal e o problema desaparece por um dia ou mais.
  2. Se, em vez de reiniciarmos o Apache, matarmos todos os processos filhos, o problema permanece (essa é a única maneira de acessarmos o status do servidor, que responde até que todos os processos cheguem ao estado "W").
  3. Para mim, parece que nossos scripts PHP nunca terminam quando o problema começa a acontecer, o que me fez pensar que era um problema de tempo limite do MySQL, Solr ou PHP / Apache.
  4. No entanto ...
    • Solr / MySQL respondem instantaneamente.
    • Existem muitas conexões MySQL disponíveis (usamos o AWS-RDS, o máximo de conexões permitidas é maior que o número de processos do Apache).
    • RAM ainda está bem (cada processo é de 10m x 60 = 600Mb de RAM, há até muito livre).
    • O PHP tem max_exectution_time definido como "30".
    • O Apache TimeOut está definido como "60".
    • Nós não usamos conexões MySQL persistentes.
    • Nós fazemos usar curl_setopt($conn, CURLOPT_FORBID_REUSE, 0) para consultar o Solr (espero que isso colete lixo corretamente, caso a conexão desapareça).
  5. Ainda parece que muitos processos nunca terminam ... Deixei um processo rodando enquanto matava todos os outros processos e esse processo ficou vivo por 2 horas, ainda servindo exatamente a mesma página (eu poderia ver isso em / server-status) que normalmente levam 50ms para responder.
  6. Não usamos set_time_limit(0) nem nada parecido em nosso código.
  7. Presumo que omitir set_time_limit significa que os scripts serão concluídos depois de max_execution_time .

Eu tinha uma teoria de que o ListenBacklog do Apache estava muito alto e que, sempre que matávamos os processos, 60 novos eram iniciados instantaneamente, todos tentando responder a clientes que tinham desaparecido há muito tempo. Isso explicaria porque o problema desapareceu quando reiniciamos o servidor. Mas parece que ListenBacklog não foi definido e, portanto, o padrão "511" estaria em uso. Eu tentei matar todos os processos filhos várias vezes em uma fila para liberar o backlog, mas o problema continua ... todos os novos pedidos para as páginas PHP levam uma eternidade para responder (a maioria não responde).

Configuração do PHP:

max_execution_time = 30
max_input_time = 60
safe_mode = off

Configuração do Apache:

KeepAlive off

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       60
MaxRequestsPerChild  1000
</IfModule>

Eu fiquei sem idéias ... Qualquer sugestão seria muito apreciada!

    
por user1493124 07.07.2013 / 21:45

1 resposta

1

As etapas de solução de problemas que eu recomendaria são:

  • strace -p $PID em um processo suspenso para ver quais chamadas do sistema, se houver, ele está preso em
  • lsof -p $PID nesse processo para ver se as alças de arquivo ou soquetes que estão abertos podem lhe dar uma pista
  • tcpdump -vv -A -s1500 port 80 para ver qual é o tráfego e onde a resposta está errada.
por 13.07.2013 / 05:19