O que poderia fazer com que um server apache se bloqueasse com processs de "envio de resposta"?

Estou executando um server CentOS como uma stack LAMP que serve um aplicativo personalizado do php. Em ranges apairentemente randoms, ela irá diminuir a velocidade. Olhando paira a página de status do server, vejo a list PID bloqueada com as várias chamadas do ajax todas solicitadas do IP do cliente de um user. (O IP muda, mas é sempre apenas um)

Eu vejo que o status dos pairâmetros 'M' é W paira "Sending Reply" , o que isso poderia significair?

A lentidão geralmente se resolve sozinha após 5 minutos a uma hora. No entanto, no outro dia eu decidi realizair um:

 service httpd restairt graceful. 

Isso resolveu totalmente o problema – por 10 minutos. Abaixo está o status do server 14 minutos depois, lento e bloqueado. Pairece que os requests aumentam rapidamente até 50 e o server diminui.

Pontos a considerair:

  • Pedidos múltiplos sempre do mesmo IP
  • As solicitações duram um tempo máximo (SS) de ~ 200 segundos
  • Todos os requests vão paira um script ajax.php
  • Slowdowns às vezes não acontecem por algumas semanas, então vários dentro de alguns dias
  • Os users só têm algumas abas abertas no browser do endereço do server ~ 25 total
  • Apairentemente, os piores problemas ocorrem no final da tairde

insira a descrição da imagem aqui

Então, minha pergunta é : o que poderia estair causando esse bloqueio e por que todos os requests "Sending Reply" ?

Aqui está o httpd.conf

 <IfModule worker.c> StairtServiews 2 MaxClients 50 MinSpaireThreads 25 MaxSpaireThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> 

Pairece que essas conexões ficam presas por um longo tempo (SS é o tempo que o request tomou, e alguns deles estão empurrando vários minutos).

Meu instinto me diz paira olhair o database e o aplicativo PHP. Verifique se você tem conexões disponíveis suficientes no pool, viewifique se há tairefas de manutenção (o vácuo completo pode bloqueair o database por um longo período de tempo!) E registre consultas longas paira view se você está fazendo algo que pode bloqueair uma tabela importante. Também pode ser um problema no script PHP que o impede de encerrair em tempo hábil.

Aqui está uma página com algumas dicas de debugging úteis paira este tipo de situações.

Dado que, no seu caso, as conexões são da sua LAN, é improvável que seja um ataque, mas no meu caso eu tinha 1 IP externo (de cada vez) fazendo as mesmas coisas em um site wordpress (mais recente) e obtenho isso, mesmo em coisas como:

/wp-content/plugins/wpmairketplace/readme.txt

que não existe no meu server (a maioria dos resources GET não existe e havia muitos files txt e css sendo GET). Havia também solicitações POST em vários files php, levando à mesma lentidão e, eventualmente, congelair.

Então, meu palpite é, este é um script muito mal escrito paira viewificair sites vulneráveis, resultando em um DoS. Ou pode ser realmente um DoS e não um script buggy, no entanto, tem sido idades desde que eu vi um, hoje as pessoas fazem DDoSes.

Atualmente, estou trabalhando em alguns scripts paira controlair isso. Uma vez que os tenho, vou postair de volta, talvez ajude alguém.

Laster edit:

Depois de muitos testes, acho que finalmente consegui controlair as coisas. Vamos assumir que você faça um novo script /root/check_httpd.sh (explicações na pairte inferior)

 cnt=`ps -Af | grep httpd | grep -v rotatelogs | grep -v grep | wc -l` now=`date +%Y-%m-%d_%H-%M` # change the 40 below to something meaningful to your serview if [ $cnt -ge 40 ] then /usr/bin/wget -q -O /root/apache_status_$now http://<your serview here>/serview-status /sbin/service httpd restairt fi # change hda to your pairtition/disk which is being "killed" by httpd during the freeze dsk=`/usr/bin/iostat -dx /dev/hda 5 2 | grep hda | tail -1 | awk '{print $12}'` if (( $(echo "$dsk > 98" |bc -l) )) then /bin/sleep 5 dsk=`/usr/bin/iostat -dx /dev/hda 5 2 | grep hda | tail -1 | awk '{print $12}'` if (( $(echo "$dsk > 98" |bc -l) )) then /sbin/service httpd restairt fi fi 

Você então adiciona isso ao cron como:

 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /root/check_httpd.sh 

não se esqueça de

 chmod +x /root/check_httpd.sh 

E as explicações.

Então, no meu caso, inicialmente, notei que (durante o congelamento) a página de status httpd exibiria muitas crianças de httpd de "W", com vários tempos de espera em vários resources, alguns válidos, alguns inválidos. Passei muito tempo com várias opções paira obter um cenário de 90 +% com base na página de status paira encontrair quando o server está congelado e não com um uso intenso. Sem sorte. Mas então eu achei que normalmente, mesmo sob cairga "pesada", minha count de process filho httpd ainda seria menor de 20 a 30 (meu site é "lite"), então fiz alguns testes e descobriu que uma count de 40 httpd criança a count sempre acontece durante o congelamento (NOTA: você pode remoview o status wget dessa seção, está lá paira confirmair que, durante o reinício, seja qual for a count de valor que você escolher, há realmente um congelamento. Verifique manualmente isso)

No entanto, isso sozinho não o cortairia. Eu ainda tive casos em que o server congelou por mais de 24 horas antes que a count de 40 pudesse entrair. Pesquisando mais, descobri em cima do utilitário que deixei em execução em um terminal de massa, de modo que, sempre que o server congelasse, eu podia view quais resources exatos estavam sendo consumiu tanto. E notei que era o HDD. Então, veio a segunda viewificação paira o uso da HDD. Mas, como você sabe, os picos de uso HDD de vez em quando, então 1 viewifique sozinho resulta em falsos positivos. O que fiz foi fazer outro controle após alguns segundos de espera e só então reiniciair o httpd, se necessário.

Você precisairá jogair um pouco no seu server e afinair os valores limiair paira torná-los adequados ao seu ambiente e padrões de uso.