Nginx + php-fpm - Cada processo php-fpm 70-100% cpu quando executando

7

Eu tenho uma situação em que o seguinte está acontecendo:

  • Estamos no linode com 8-core, 8gb de ram, 2,6ghz - usando nginx + php-fpm - estamos recebendo gráficos extremamente altos de uso da CPU (que não queremos ser tão ruins VPS vizinho) ...

  • Temos cerca de menos de 100 usuários no site por vez - então, essa situação também é incrivelmente constrangedora - que o uso da CPU seja muito alto.

  • Estamos usando um framework muito desconhecido, possivelmente intensivo em php, questionávelmente horrível, em vez de outras estruturas bem conhecidas, bem documentadas e bem elaboradas, como wordpress ou drupal, nas quais há MUITA documentação sobre caching (assim como plugins que lidam com caching) php em uma plataforma nginx + php_fpm.

  • Assim, temos cerca de 6 processos php-fpm abertos que, ao EXECUTAR, consomem quantidades de CPU individualmente grandes (mais de 30 e quase 99%) - e não tenho a menor idéia de como parar eles de usar tanto cpu. Eu não posso dizer quais scripts php estão causando esses picos, porque eles estão acontecendo o tempo todo ... geralmente apenas 1 ou 2 estão em execução - mas quando todos os 6 executados maximizamos todos os 8 cpus.

  • Meu arquivo pool.d / www.conf possui as seguintes configurações:

    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 4
    pm.min_spare_servers = 2
    pm.max_spare_servers = 6
    
  • Fizemos isso ^ setup porque, da maneira que estou interpretando, nossa memória é realmente incrível (htop mostrando 472/7000 + mb usado, sem troca, etc.) e nós poderíamos lidar com muito mais processos e quebrar na fila esperando para ser processado - MAS, infelizmente, uma vez que cada processo é muito intenso em nossa CPU durante a execução - acabamos levando o nosso CPU para o alto - para que não possamos lidar com processos suficientes.

  • A questão - o que é que podemos fazer para reduzir o uso do CPU do processo php-fpm para que possamos aumentar as configurações nesse arquivo conf do conjunto para php-fpm - e também sim, o /var/log/php5-fpm.log está gritando para aumentar nossos filhos e ajustar / aumentar nossos servidores min / max / start. Mas isso faz com que nossa carga fique louca, como afirmamos anteriormente. Como podemos fazer isso sem necessariamente usar um cache ou quais são nossas opções?

  • Minha ideia? Eu li coisas sobre o uso de cpulimit para garantir que nenhum processo leva mais do que uma quantidade atribuída de cpu - mas isso vai atrasar as coisas para ser inutilizável? Ou, ao fazer isso, poderíamos aumentar nossa capacidade de executar mais do que alguns processos - também pensava em executar dois pools - um para nosso site voltado para a frente (o que os clientes experimentam) e outro para um back-end (que está afetando nosso site quando enfrentamos o tempo) os relatórios de consumo estão sendo executados).

  • Eu tenho passado alguns dias pesquisando, pesquisando, etc. sobre esse tópico - e é difícil porque a situação de todos é tão exclusiva para o sistema deles - o problema é estar em uma situação inédita, possivelmente ruim escrita - framework - está dificultando encontrar uma solução. Nós não podemos simplesmente descartar este framework ainda - eu tenho que encontrar uma solução de algum tipo.

ATUALIZAÇÃO: Implementei o memcache para armazenar sessões php - porque a estrutura depende muito das sessões do usuário e a natureza do nosso sistema é que os funcionários geralmente usam várias guias de cada vez - cada um retornando às sessões para confirmar habilidades / usuário data / etc ... por isso, espero ver algum aumento no desempenho com isso - bem-vindo ao comentar que, se quiser, veremos como será o amanhã, quando passarmos por nossos horários de maior volume.

    
por amurrell 13.02.2014 / 22:09

2 respostas

6

Algumas coisas a serem consideradas (desculpas antecipadas se você já considerou isso): Primeiro de tudo, certifique-se de otimizar a configuração do nginx e invocar o php-fpm somente quando for absolutamente necessário. A última coisa que você quer fazer é deixar o php manejar coisas como páginas HTML estáticas (o que fará felizmente).

Em segundo lugar, como você está usando o php-fpm, sugiro ser mais agressivo com o tempo que os filhos do php-fpm podem viver. Você precisa encontrar o ponto ideal entre os fios / filhos pouco vividos e a estabilidade. Os padrões php-fpm são muito generosos para qualquer sistema de produção, IMHO. Quanto mais tempo um funcionário tiver permissão para atender a solicitações, mais instável ele ficará. Há também um risco maior de vazamentos de memória, e se essa estrutura a que você se refere tem erros como loops infinitos, o que pode estar causando dor com carga da CPU, isso não deve doer.

Eu reduziria o número de pm.max_requests para seus pools de produção. Eu acho que o padrão é 200. Eu começaria de 50 e veria onde isso leva você.

Em caso de falha / complementar a isso, você também pode tentar essas opções globais (AFAIK, todas elas estão desativadas por padrão):

emergency_restart_threshold 3
emergency_restart_interval 1m
process_control_timeout 5s

O que isso significa? Se 3 processos-filhos do PHP-FPM saírem com SIGSEGV ou SIGBUS (ou seja, travar) dentro de 1 minuto, o PHP-FPM deve reiniciar automaticamente. Os processos filhos aguardam 5s por uma reação nos sinais do mestre.

Aqui está uma boa visão geral de todas as opções de configuração que mencionei aqui, além de outras: link

Espero que essas dicas o ajudem! Lembre-se de ajustar e observar, infelizmente não parece haver uma regra para tudo isso, como você observou, existem muitas variáveis que afetam o comportamento e a estabilidade do PHP.

Finalmente, o recurso de limitação de CPU que você perguntou é documentado aqui , mas eu só usaria para isso, se você esgotar todas as outras opções. Se você escolher esse caminho, eu definitivamente ficaria atento a possíveis interações entre ajustes do PHP-FPM e sua configuração de limits.conf. Nesse ponto, o etckeeper pode ser um salva-vidas! :)

Boa sorte!

Rouben

    
por 16.02.2014 / 09:55
3

Você está executando o cache de opcode, certo?

Costumava ser a APC que era o destino, mas tem sido um buggy por um bom tempo, e foi substituída por Zend Opcache , que agora faz parte do PHP desde o 5.5, e tem um backport no PECL para 5.3 e 5.4.

    
por 16.02.2014 / 14:40