Problemas de memória do Apache

4

Então, tenho certeza de que isso já foi perguntado, mas quero ter certeza de que estou obtendo as informações corretas.

Estou rodando uma caixa 360 Linode com o Debian 5 e o Apache 2.2. Eu compilei tudo sozinho (sem apt-get). De vez em quando (uma vez a cada poucas semanas?), Meu servidor aleatoriamente "travava": ele disparava até 100% da CPU (na verdade 400%, mas você sabe o que eu quero dizer) e entregava a caixa. Você não conseguiu SSH para ver qual era o problema e o próprio servidor parou de aceitar conexões. A única maneira de consertá-lo era reiniciar a caixa.

Recentemente, começou a acontecer com relativa frequência: 24 horas, 12 horas, 10 horas, 8, 6, 4. Finalmente, consegui dar uma espiada logo antes de trancá-la dois dias atrás. Eu notei que o disco IO estava elevado e que quase não havia mais memória RAM! Além disso, havia uma carga de barcos de processos httpd rodando em 3-4% de RAM. E por carga de barco, quero dizer, quando eu fiz um ps -ef, eles ocuparam toda a tela. Se você rolou para cima, eles pegaram todo o buffer para o meu cliente SSH.

Então eu fiz alguns ajustes no meu código pensando que algo não estava fechando corretamente. Corrigi problemas de memória em meu PHP, ativei um registro de erros mais granular e corrigi vários erros, e isso pareceu ajudar em algum grau. As falhas voltaram a cada 24 horas.

Estou convencido de que isso é causado porque há muito pouca memória, e o volume de ocorrências que recebo está chutando meu servidor na troca. Como há tantas solicitações atingindo a troca, o disco IO dispara pelo telhado, fazendo com que o uso da CPU seja disparado pelo telhado, fazendo com que meu servidor trave.

Veja o que eu fiz para tentar corrigi-lo: eu fiz alguma pesquisa e descobri que provavelmente deveria estar usando o prefork. Eu olhei ao redor na minha configuração e não consegui encontrar nenhum ServerLimit ou MaxClients ou algo parecido, então eu adicionei alguns valores "padrão" e meu servidor se recusou a aceitar / qualquer / incoming conexões. Efetivamente, os valores do prefork bloquearam todo o tráfego HTTP de entrada sufocando a conexão (talvez porque meu servidor não seja capaz de lidar com o prefork? Idk).

Do jeito que eu vejo, o que meu servidor "costumava fazer" era bom, exceto que todo o processo do apache ficava pendurado e vazando memória. Existe alguma maneira de definir um tempo limite em processos do Apache ou colocar um limite em quantos deles existem? Parece muito burro que a melhor solução é usar o prefork; Eu tenho que imaginar que há uma maneira melhor.

Obrigado rapazes

    
por mattbasta 06.11.2009 / 20:24

4 respostas

1

Parece que você está aprendendo da maneira mais difícil que o PHP é um invasor de memória e não é particularmente escalável.

Algumas sugestões, sem nenhuma ordem específica:

Se você ainda suspeitar de um vazamento de memória, defina MaxRequestsPerChild como valor realmente baixo.

Considere comprar mais memória, 360 megas não é muito hoje em dia.

Tente encontrar um tamanho médio de processo httpd executando ps ou top e, em seguida, configurando MaxClients para que tudo sempre caiba na memória. Trocar é uma espiral de morte, quanto mais lento você estiver processando as requisições, mais processos o apache precisa usar, mais memória.

Se você laod php como um módulo no apache, ele é carregado para cada solicitação, seja um script ou um arquivo estático (uma imagem ou css ou .js ou outros). Considere servir conteúdo estático de um servidor separado ou usar fastcgi ou um proxy reverso como nginx para que o apache sirva apenas para php limitar o número de instâncias php de gordura que você precisa manter na memória.

    
por 07.11.2009 / 14:34
0

Eu acho que sua máquina está se debatendo com pouca memória. Na minha experiência, todo processo de apache que está sendo executado tem o potencial de ocupar um monte de memória. Se você tem o php rodando como um módulo no apache procure em seu php.ini qual o valor para memory_limit = . Eu tinha 128M, o que é bastante quando você tem apenas 10 processos de apache em execução. Eles podem não levar essa quantia desde o início, mas se o seu aplicativo PHP tiver memória ou realmente precisar de 128M, você pode atingir o limite de seus servidores com bastante facilidade.

Minha recomendação é: RAM física dividida por memory_limit igual a max_procs

    
por 06.11.2009 / 21:22
0

Se você está realmente com pouca memória, você pode tentar rodar algo como lighttpd ou nginx com php como um processo fastcgi, eu não usei muito o nginx, mas eu uso o lighttpd allot e tem uma sobrecarga de memória / cpu extremamente baixa. / p>

Lighttpd e php via tutorial fastcgi

    
por 16.12.2009 / 00:27
0

Você tem algum back-end de banco de dados ao qual está se conectando? Muitas vezes o que acontece é que se algumas consultas começarem a abrandar, você terá processos apache começando a fazer backup e, dada a baixa quantidade de RAM no seu linode, ele irá se acumular e cair, fazendo com que a CPU e a carga disparem.

Outra coisa, você mencionou que está usando o modelo de trabalho. Isso é bom se você estiver 100% certo de que todos os módulos que você está usando no PHP são thread-safe. O manual de instalação do php real recomenda contra usá-lo embora ( php manual ) ... Independentemente de qual modelo você escolher, é necessário ajustá-los corretamente. Um bom ponto de partida é Sistemas Tuning LAMP . Se o MaxClients não for ajustado adequadamente, o Apache pode acabar causando o travamento do seu sistema, pois ele ocupa toda a memória durante um aumento de tráfego no seu site.

    
por 25.01.2010 / 03:57