Wordpress (cache nginx + Apache + fcgid) atrelando todas as 8 CPUs

1

Eu tenho um site multi-usuário WordPress que coloca todas as minhas CPUs em mais de 90% de uso:

top - 12:02:58 up 55 days,  5:25, 10 users,  load average: 20.51, 15.66, 14.90
Tasks: 294 total,  24 running, 270 sleeping,   0 stopped,   0 zombie
Cpu0  : 87.5%us,  8.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  4.5%si,  0.0%st
Cpu1  : 97.9%us,  1.9%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu2  : 96.0%us,  3.5%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Cpu3  : 97.6%us,  2.1%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu4  : 97.1%us,  2.7%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu5  : 97.9%us,  1.9%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu6  : 97.9%us,  1.6%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Cpu7  : 96.0%us,  3.5%sy,  0.0%ni,  0.3%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:  14369424k total, 11903548k used,  2465876k free,   402360k buffers
Swap:  4063200k total,  3594784k used,   468416k free,  1484116k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                              
30658 apache    16   0  274m  97m 6304 R 62.1  0.7   0:12.49 php-cgi
30686 apache    16   0  213m  92m 6040 R 52.2  0.7   0:03.27 php-cgi
30685 apache    15   0  211m  87m 5764 S 50.3  0.6   0:04.50 php-cgi
28217 apache    16   0  529m 405m 6748 S 49.0  2.9   3:54.72 php-cgi
30468 apache    16   0  414m 291m 6452 R 48.5  2.1   0:49.78 php-cgi
29604 apache    15   0  258m 135m 6464 S 47.4  1.0   2:16.22 php-cgi
28308 apache    16   0  584m 408m 6724 R 43.9  2.9   3:43.07 php-cgi
28266 apache    16   0  550m 374m 6728 R 43.7  2.7   3:58.38 php-cgi
29573 apache    16   0  584m 407m 6592 R 36.8  2.9   1:59.88 php-cgi
30470 apache    16   0  219m  95m 6452 S 36.5  0.7   0:39.66 php-cgi
29138 apache    15   0  513m 334m 6528 S 33.6  2.4   2:03.14 php-cgi
30472 apache    17   0  441m 318m 6272 R 31.7  2.3   0:50.45 php-cgi
28283 apache    16   0  414m 291m 6580 R 29.3  2.1   3:53.06 php-cgi
29858 apache    16   0  251m 127m 6628 R 24.8  0.9   1:15.53 php-cgi
28253 apache    18   0  550m 374m 6580 R 24.5  2.7   4:08.05 php-cgi
30666 apache    15   0  217m  94m 5996 R 24.5  0.7   0:04.68 php-cgi
28208 apache    20   0  584m 407m 6436 R 24.2  2.9   4:36.36 php-cgi
29085 apache    25   0  358m 182m 6488 R 22.6  1.3   2:19.76 php-cgi
28258 apache    25   0  530m 407m 6512 R 22.4  2.9   3:58.70 php-cgi
29574 apache    16   0  530m 406m 6540 S 21.6  2.9   2:19.26 php-cgi
28947 apache    16   0  524m 401m 6476 R 14.1  2.9   2:32.33 php-cgi
28238 apache    15   0  488m 312m 6852 S 12.3  2.2   4:24.34 php-cgi
30464 apache    15   0  274m 151m 6176 R 11.2  1.1   0:19.67 php-cgi
28293 apache    16   0  269m 146m 6460 R  9.9  1.0   3:57.17 php-cgi
28205 apache    25   0  530m 407m 6496 R  9.6  2.9   4:05.49 php-cgi
30471 apache    19   0  263m 140m 6440 R  6.9  1.0   0:47.42 php-cgi

A saída mostra que a maior parte da CPU usada por um processo individual é ~ 60%, mas houve momentos em que eu tive até 7 processos usando mais de 90% de cpu.

O site é executado da seguinte forma:

  1. O nginx funciona como um proxy reverso, atendendo a todos os arquivos estáticos possíveis e armazenando páginas em cache por meio da diretiva proxy_cache.

  2. Ele delega ao Apache quando scripts PHP são necessários. Estes são executados via mod_cgi usando a opção ExecCGI

  3. O Apache e o nginx fazem compactação em todos os arquivos legíveis por humanos

  4. Para evitar acertar o MySQL o tempo todo, nós salvamos fragmentos HTML no memcached, que atualmente armazena em cache entre 2 e 4MB, conforme relatado pelo comando stats em uma conexão telnet

  5. Há também alguns contadores mantidos em um banco de dados Redis, principalmente para contar as visualizações de página para cada postagem.

  6. Sem WP Super Cache (o nginx faz o cache), sem o XCache.

Não sei como determinar exatamente o que cada processo php-cgi está fazendo para exigir uma demanda tão alta de CPU - o site foi bastante modificado por várias equipes de software diferentes antes de começarmos a dar manutenção.

O log de erros do PHP mostra principalmente esses erros:

  1. "Não é possível redeclarar a classe FacebookRestClientException"
  2. "Chamada para a função indefinida e _ ()"
  3. Sintaxe SQL inválida, principalmente aqui: "WHERE post_id = xxxxx AND blog_id="
  4. "Tamanho de memória permitido de 268.435.456 bytes esgotados"
  5. "Chamada para o método indefinido Services_JSON :: encodeUnsafe ()"

Nenhum deles realmente realiza cálculos, então eles não podem ser a fonte do problema da CPU.

Eu tentei rastrear chamadas do sistema e vi o lstat, ler, escrever e acessar, o que geraria espera e não carregamento da cpu se fossem o problema (correto?). Além disso, houve chamadas para a pesquisa e seleção.

Alguém poderia me dar dicas sobre o que verificar em seguida?

    
por ptn777 04.08.2012 / 19:15

3 respostas

1

Seu problema está aqui:

No WP Super Cache (nginx does the caching), no XCache.

Instale o APC Zend OPcache e o W3 Total Cache e observe seu uso da CPU cair para quase nada.

APC O Zend OPcache sozinho deve lhe dar um pouco de espaço para respirar.

Observe que o W3 Total Cache não é totalmente compatível com vários sites e, portanto, precisa ser configurado em cada site individualmente. Ele pode ser configurado para usar seu memcached existente para armazenamento em cache.

Você também pode se livrar do Apache. Não está fazendo absolutamente nada para você.

(Nota: APC é obsoleto e provou não ser confiável na prática. Atualmente, eu recomendo usar o Zend OPcache).

    
por 04.08.2012 / 19:25
1

A julgar pelos outros erros que você está vendo, seria muito surpreendente se não houvesse algum código mal pensado à espreita - uma revisão de código seria a melhor maneira de abordar solução de problemas.

Cannot redeclare class FacebookRestClientException

Sabemos que essa classe foi carregada com êxito, então eu começaria descobrindo quais APIs externas os scripts estão chamando, se estão ou não em falha e por quanto tempo eles ligam as coisas durante a execução (ou falha na execução) - uma chamada mal pensada (ou uma série de chamadas) para uma API externa pode ser responsável.

    
por 04.08.2012 / 19:45
0

O armazenamento em cache de memória definitivamente ajudará, particularmente para o cache de objetos internos do WordPress. Como Michael diz, o W3 Total Cache não é totalmente compatível com vários sites e é bastante abrangente / complicado / pesado, então eu recomendo uma alternativa mais pura e simples que seja muito semelhante à configuração em wordpress.com: Cache de objetos APC (que é mais rápido que o memcached para servidores únicos) para o cache de objetos e Batcache para cache de memória de página inteira. Preste atenção nas instruções de instalação para cada um, elas são diferentes dos plugins padrão.

Obviamente, você precisará instalar o APC para PHP se ainda não o tiver feito e ajustá-lo adequadamente. Por exemplo, stat = 0 irá acelerar as coisas significativamente, mas se você definir isso, então você precisará reiniciar o processo PHP quando qualquer arquivo PHP for alterado (por exemplo, em upgrades de plugins e wordpress). Certifique-se de instalar o painel apc.php (você pode ter que obter isso do tarball de origem da APC, dependendo dos pacotes do seu sistema operacional), é muito útil para ajuste e depuração. (Bloqueie / senha protegê-lo, mente.)

Como alternativa, já que você já tem o memcached instalado, existe o plugin Memcached Redux , que serve a mesma função como o cache de objetos da APC. Este pode ser o caminho mais fácil.

Você pode não obter uma enorme quantidade de benefícios do Batcache, pois já está usando o nginx para um proxy_cache baseado em arquivo, mas certamente não vai doer se tiver alguma memória de sobra e puder ajudar colmatando a lacuna entre o cache de arquivos e diretamente atingindo o Apache, então vale a pena tentar.

Olhando para o seu ponto 3. Eu recomendaria altamente desabilitar o gzip em Apache & PHP, por exemplo, desative mod_deflate e altere zlib.output_compression = Off em php.ini. O Nginx é o seu frontend, então você fará a compressão para você de qualquer maneira, então não há necessidade de fazê-lo duas vezes - o nginx provavelmente irá fazê-lo mais rápido / eficientemente e economizará a CPU do processo Apache / PHP.

Quantos plugins estão ativados? Eles são todos essenciais? Você pode desativá-los um por um e ver que diferença cada um faz? Já vi alguns plugins terrivelmente codificados que prejudicaram completamente os sites, portanto, faça uma auditoria desses, se puder.

Você menciona que o site foi bastante modificado por várias equipes de software diferentes. Existe algum controle de versão para que você possa ver quais alterações foram feitas? Eles estão diretamente no núcleo, no tema ou nos plugins? Se eles estão no centro, você pode diferenciar as coisas para obter uma imagem melhor ou é muito modificado? Indo adiante, refatorando as alterações do núcleo para o tema do site functions.php & plugins discretos podem tornar sua vida muito mais fácil, se você puder fazê-lo.

    
por 10.08.2012 / 01:43