O que há de errado na minha configuração php-fpm?

8

Eu tenho um servidor de 64 bits, mas apenas 256 MB de RAM. Então, mudei para o servidor nginx com o fast-cgi para conectar-se ao PHP. Eu tenho o PHP 5.3.6 em execução.

O problema é que, a cada dois ou três dias, quando tento acessar qualquer página PHP, recebo um erro interno do servidor. A única maneira de contornar é reiniciar o php-fpm manualmente. Isso significa que eu deveria ter definido alguns parâmetros errados que estão causando o engasgo. Abaixo, listei as configurações relevantes.

/etc/php-fpm.conf: -

include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0

/etc/php-fpm.d/www.conf: -

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

/etc/nginx/php.conf: -

location ~ \.php {
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        fastcgi_pass unix:---some-location---;
}

Atualização 1

E eu tenho quatro processos nginx em execução. Em média, cada processo php-fpm ocupa 35 MB de RAM (tamanho da memória virtual de 320 MB cada). Eu também tenho um processo MySql em execução.

Atualização 2

Esqueci de colar os logs.

log de erros do php-fpm: -

WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...

php-fpm www.error log: -

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
AppleGrew
fonte

Respostas:

17

Uma recomendação imediata seria diminuir os valores definidos - provavelmente cortá-los ao meio.

Você tem: pm.max_children = 10 Se você disser 35 MB / processo = 350 MB; em uma caixa de 256 MB, isso significa muitas trocas ou você fica sem memória - nenhuma delas é boa.

Eu diria que pegue pelo menos 100 MB para outros processos, talvez até 150 MB para serem seguros, e depois divida esse número por 35 MB para obter seus max_children. Mantenha todos os outros números alinhados:

pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500

Pare o PHP-FPM e corra freepara ter uma idéia da sua memória disponível - divida por 35 MB para obter seus max_children.

Dependendo da quantidade de memória que o MySQL ocupa, você pode ter que deixar max_children para 3.

Acho que os processos PHP-FPM compartilham muita memória, fazem um experimento rápido para determinar quanto é realmente usado. Pare o PHP-FPM e execute free. Inicie o PHP-FPM, visite algumas páginas comuns (necessárias, pois a memória aumenta dependendo das páginas carregadas) e verifique a memória total usada, novamente usando free- divida a diferença pelo número de processos. Não é um sistema perfeito, mas acho que é bastante preciso (às vezes a coluna de dados no topo também não é ruim).

cyberx86
fonte
Eu paro freee começo. Divido essa memória livre por 35 para obter o max_children value. Não entendi o propósito do último parágrafo.
AppleGrew
Parece que posso suportar apenas no máximo 2,3 processos do PHP. : P Enfim, agora tenho max_children3.
AppleGrew 30/07
a) O objetivo do 'último parágrafo' era obter um valor mais preciso do quanto um processo PHP consome. Acho que o valor de ps ou top nem sempre corresponde à queda na memória disponível. Se encontrar a memória disponível, execute alguns processos PHP e avalie novamente a memória disponível (em vez de examinar a memória usada pelos processos), você poderá obter um valor 'alternativo' (e talvez melhor) para quanta memória cada processo usa. b) O parâmetro memory_limit sugerido por invarbrass também é uma boa sugestão. c) Dê uma olhada no script mysqltuner.pl, ele pode ajudar na sua configuração do banco de dados.
22811 cyberx86
@ cyberx86, que valor freevocê leva em consideração? O da linha '- / + buffers / cache' que é usado para o cache do disco, mas é realmente gratuito para aplicativos?
Roman Newaza
@RomanNewaza - sim, você deseja examinar a memória disponível para o aplicativo e usar a entrada como 'free' em '- / + buffers / cache'.
cyberx86
6

Sua configuração php-fpm parece OK.

Mas o servidor que você está executando é um pouco restrito a recursos. É óbvio pelos logs que os processos PHP estão esgotando a memória disponível.

Adicionando as sugestões fornecidas pelo cyberx86:

Você pode tentar editar o parâmetro memory_limit no arquivo php.ini (veja aqui ) (embora eu não tenha certeza de que fará muito bem)

Dada a pequena quantidade de memória do sistema, acho que você deveria considerar seriamente mudar para o SO de 32 bits. Usar um sistema operacional x64 está prejudicando você, em vez de ser benéfico.

Se você não estiver utilizando o armazenamento InnoDB no banco de dados MySql, considere também desativar o InnoDB no my.cnf - ele economizará outros 100 MB de RAM.

O Lowendbox tem um ótimo tutorial sobre como otimizar servidores para configuração de pouca memória.

invarbrass
fonte
Bem, minha voz ficou rouca ao tentar argumentar com minha empresa de hospedagem para fornecer SO de 32 bits para mim. Parece que em toda a rede essas empresas fornecem apenas 64 bits. Eu encontrei apenas uma empresa que fornece SO de 32 bits, mas elas são muito mais caras.
AppleGrew
3

Um comando muito útil para encontrar a memória obtida pelo php:

ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Então você divide a RAM que deseja dedicar ao php e tem o seu valor max_children!

Além disso, você pode monitorar manualmente (você deve configurar o ponto de extremidade php-status) ou com o Nagios.

Thomas Decaux
fonte
awk: fatal: division by zero attempted
Samayo
1
Significa que você não possui um processo php5-fpm .... você precisa alterar o nome do processo "php5-fpm" para se adequar ao seu.
Thomas Decaux
Eu usei esse comando ps --no-headers -o "rss,cmd" | grep php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'De alguma forma, as opções -C não funcionam.
dieend
Tente executar o comando separadamente (I média ps --no-headers -o "rss, cmd" primeira etc ...) isso deve ser fácil de depurar
Thomas Decaux