Nginx + php-fpm - cada php-fpm processa 70-100% da CPU ao executar

8

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

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

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

  • Estamos usando um Framework muito desconhecido, possivelmente intensivo em termos de CPU, questionável e horrível, em vez de outros frameworks bem conhecidos, bem documentados e bem criados, como wordpress ou drupal, nos quais há MUITA documentação sobre cache (além de plug-ins) que lidam com o cache) php em uma plataforma nginx + php_fpm.

  • Portanto, temos cerca de 6 processos abertos de php-fpm que, quando EXECUTANDO, consomem individualmente GRANDES (30+ e quase 99%) quantidades de CPU - e eu não tenho a menor idéia de como impedi-los de usar tanta CPU . Não sei dizer quais scripts php estão causando esses picos porque estão acontecendo o tempo todo ... geralmente apenas 1 ou 2 estão em execução - mas quando todos os 6 são 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 poderíamos lidar com muitos outros processos e quebrar a linha esperando obter processado - MAS, infelizmente, como cada processo é muito intenso em nossa CPU durante a execução - acabamos conduzindo nossa CPU pelo telhado - para que não possamos lidar com processos suficientes.

  • A questão - o que diabos podemos fazer para reduzir o uso da CPU do processo php-fpm para aumentar as configurações no arquivo conf do pool para php-fpm - e também sim, o /var/log/php5-fpm.log está gritando conosco para aumentar nossos filhos e ajustar / aumentar nossos servidores min / max / start. Mas fazer isso faz com que nossa carga fique louca, como afirmado 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 do cpulimit para garantir que nenhum processo leve mais do que uma quantidade alocada de cpu - mas isso atrasará as coisas para que não sejam utilizáveis? Ou, ao fazê-lo, poderíamos aumentar nossa capacidade de executar mais do que alguns processos - eu também pensei em executar dois pools - um para o site voltado para a frente (o que os clientes experimentam) e outro para um back-end (que está afetando nosso site voltado para a frente quando relatórios de consumo estão sendo executados).

  • Passei alguns dias pesquisando, pesquisando no Google, etc., sobre esse tópico - e é difícil porque a situação de todos é tão única em seu sistema - o problema está em uma estrutura tão específica, desconhecida e possivelmente mal escrita - está criando difícil encontrar uma solução. Também não podemos descartar essa estrutura ainda - tenho que encontrar uma solução de algum tipo.


ATUALIZAÇÃO: Eu 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 costumam usar várias guias por vez - cada uma consultando as sessões para confirmar as habilidades / dados do usuário / etc ... por isso, espero ver algum aumento no desempenho disso - seja bem-vindo a comentar sobre isso, se quiser - verei como será amanhã quando passarmos por nossos horários de pico de volume mais altos.

amurrell
fonte
O Nginx não é muito bom para um aplicativo da Web com uso intensivo de CPU - mas nossa CPU alta é ruim - muito ruim - e estamos trabalhando para corrigi-lo. Não há uma configuração máxima de clientes máxima, pois DEVE ser capaz de suportar um número decente de clientes - mas o alto uso da CPU por processo distorce essa capacidade. Mudamos para o apache apenas porque ele LITTLE é melhor com alto uso da CPU - mas, em última análise, esse problema é mais indicativo de um problema de aplicativo da web e pode demorar um pouco para ser resolvido, mas não há tempo como o presente para começar a corrigi-lo.
amurrell
Quando você vai ao médico e ele diz para você tomar certos remédios - porque ele sabe que você não escuta as declarações "pare de beber refrigerante e coma fast-food" - é exatamente por isso que não houve uma grande resposta para mim - porque a verdade é que , nenhuma configuração ou correção rápida é realmente aplicada - apenas a triste verdade de que precisamos alterar drasticamente nosso próprio aplicativo da web.
amurrell
Felizmente, se você tiver esse problema com uma estrutura popular, poderá ter a opção de aproveitar o cache e a documentação abundante sobre ela - mas estamos em uma coisa aleatória obscura que não podemos mudar, exceto a própria estrutura. Yay!
amurrell
1
Então, pelo que entendi, o opcache está armazenando seu código PHP como binário e pode ser consumido pelo php-fpm muito mais rápido (cache), mas você também deve utilizar o cache de objetos. Um exemplo é armazenar uma saída de página inteira como um "objeto" "em algo como memcached. Isso na verdade armazenaria em cache a saída da página (ou outras coisas que você deseja, como as sessões de php, etc) ... Em seguida, você também pode usar o verniz, que é um proxy reverso - mas basicamente é um intermediário entre a solicitação e o servidor, para que o seu o servidor não está sendo atingido com solicitações diretamente - e funciona a partir da memória para atender aos URLs em cache.
amurrell
1
O verniz é incrível para isso - armazenar uma cópia em cache do que foi obtido do servidor na memória - para que o verniz consiga grande parte da carga. Meu empregador atual está no nginx e usamos verniz e memcached. Felizmente, a estrutura em que estamos agora tem seu próprio mecanismo de cache para determinar o cache da página (dados da página gerados). No meu último trabalho, eu mesmo escrevi na estrutura - não foi divertido, mas funcionou. Apache - eu não voltaria, a menos que você não tenha tempo para corrigir o nginx. única solução para não matar totalmente o nosso projeto enquanto escrevia o mecanismo de cache.
amurrell

Respostas:

6

Algumas coisas a considerar (desculpas antecipadamente, se você já considerou estas): Primeiro, certifique-se de otimizar sua 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 manipular coisas como páginas HTML estáticas (o que ele fará com prazer).

Em segundo lugar, como você usa o php-fpm, sugiro que seja mais agressivo quanto tempo as crianças do php-fpm têm permissão para viver. Você precisa encontrar o ponto ideal entre threads / filhos em breve e estabilidade. Os padrões do php-fpm são generosos demais para qualquer sistema de produção, o IMHO. Quanto mais tempo um trabalhador tiver permissão para atender solicitações, mais instável ficará. Também há um risco maior de vazamento de memória e, se essa estrutura a que você se refere tiver bugs como loops infinitos, o que pode causar luto pela carga da CPU, isso não deve prejudicar.

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

Falhando / complementar a isso, você também pode tentar estas 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 isto 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 esperam 5s por uma reação aos 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: http://myjeeva.com/php-fpm-configuration-101.html

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

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

Boa sorte!

Rouben

Rouben
fonte
Vou tentar limitar o max_requests amanhã - parece que cada processo que permitimos quer consumir a CPU, então essa pode ser uma boa ideia. Estamos utilizando os limites de reinicialização de emergência, mas meus números foram um pouco mais altos - vou experimentar o seu e ver como as coisas vão. Obrigado pela sua atenção - muito apreciada. Queria saber sua opinião sobre o cache? Eu estou querendo saber se a utilização de cache php significa que o quadro teria que ser adaptado para lidar com isso. Eu sou muito novo nesse conceito.
amurrell
3

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

Costumava ser a APC que era o principal item aqui, mas já é um bug há algum tempo, e foi substituída pelo Zend Opcache , que agora faz parte do PHP desde 5.5 e tem um backport no PECL para 5.3. e 5.4.

Michael Hampton
fonte
Estou interessado neste Zend OpCache - Estamos no 5.3 - Se você pudesse expandir essa resposta, eu realmente aprecio!
amurrell
Tivemos o xcache - mas agora eu optei pelo Zend Opcache e o instalei e confirmei que ele está funcionando no phpinfo (). Eu vou deixar você saber se o nosso desempenho é melhor como resultado cruza os dedos
amurrell
Eu tive que desativar o zend opcache por enquanto - tudo estava funcionando, exceto qualquer arquivo css ou js gerado por php dinâmico. Tentei colocar esses arquivos na lista negra do opcache - mas a lista negra não funcionou ou não sei dizer por que o opcache está fazendo com que o nginx obtenha 502 erros de gateway inválidos apenas para esses arquivos. O que eu preciso deles para o modelo e eles fazem parte do quadro ruim. Nos logs do nginx, recebi toneladas de readv com falha - erro de conexão de 104 pares.
amurrell