O estranho caso do Sr. Time To First Byte

14

Eu tenho um servidor web em um Linode 1024 VPS baseado em

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6 (com PHP-FPM, APC)
  • Verniz 3.0.2

E alguns blogs baseados no WordPress 3.3.1. Um deles é um blog simples, com a configuração padrão, o tema e apenas a publicação "Hello World", para testar o servidor. O outro é um blog clonado de outro servidor, com quase 10 mil posts e mais de 10 mil comentários. Este blog tem cerca de 5k exclusivos por dia.

O servidor fornece bons números em um teste ab para o blog de teste , mas é impossível fazer o mesmo teste com o blog clonado: o teste ab carrega muito o servidor e eu tenho que parar o processo, o que faz com que ab seja exibido esse resultado realmente ruim .

O htop também mostra uma carga "normal" quando em operação normal , mas uma carga anormal durante o teste de ab.

Há outra coisa estranha acontecendo (a mais importante para mim): o Time To First Byte é extremamente alto , mas depois disso, o site carrega muito rápido. Isso pode ser facilmente testado com serviços como tools.pingdom.com, que fornece esse resultado . Por favor, preste atenção na região amarela que significa "tempo de espera".

Por que isso está acontecendo? Idéias possíveis:

  • Configuração incorreta do PHP-FPM
  • O tempo de resposta do DNS Linode é péssimo. Bobagem - o blog de teste resolve o problema do DNS, o TTFB é fantástico
  • Configuração incorreta do Nginx

Caso alguém precise de mais informações,

javipas
fonte
Eu acho que isso pode ter algo a ver com a if -fdiretiva que você está usando no locationcontêiner na configuração do nginx. Com base no que estou lendo aqui , wiki.nginx.org/Pitfalls , sinto que -festá fazendo uma pesquisa ineficiente pelo arquivo, o que poderia causar um problema de tempo até o primeiro byte, especialmente se você tiver diretórios com um grande número de arquivos.
precisa saber é o seguinte
1
Algumas reflexões: a) quais são as diferenças do servidor original do qual o blog é clonado (por exemplo, ele executa a mesma pilha?) B) se possível, execute ab diretamente do servidor usando o host local e a porta. Tente acessar via verniz e, em seguida, acesse diretamente o nginx). c) Ative os logs lentos do MySQL e PHP-FPM. d) execute mysqltuner.pl e veja se você pode melhorar seu desempenho no MySQL (essa seria a diferença mais óbvia entre os blogs - ou plugins). e) A configuração do PHP-FPM que você postou não parece ser a usada pelo nginx (/var/run/php5-fpm-tpnet.sock! = /var/run/php5-fpm-www-data.sock)
cyberx86
1
Definitivamente um problema de PHP. Wordpress é realmente lento. Você deseja um plug-in de armazenamento em cache para obter um tempo de carregamento decente quando tiver muito conteúdo.
Martin Fjordvald 15/01/12
2
Você disse que 'pode executar ab no localhost e obter 4k req / s' - a qual localhost (anterior / atual) você está se referindo? Se esse valor é do seu servidor atual - aquele com alto TTFB -, seu problema ficou muito mais interessante - pois você eliminou efetivamente o PHP, o MySQL e o seu servidor da web. TTFB inclui DNS, tempo de ida e volta e tempo de processamento. Um TTFB longo geralmente é devido ao processamento (por exemplo, PHP / MySQL). O ponto de executar ab diretamente no nginx é eliminar os outros componentes. Além disso, o verniz, se configurado corretamente, deve ignorar o back-end, fornecendo uma quantidade muito alta de solicitações.
cyberx86
1
Seus testes de host local não parecem válidos - você realmente não recuperou seu blog. Observe a diferença no tamanho da página: 7500 bytes quando acessados ​​do domínio, 151 bytes do localhost. Como você provavelmente possui vários virtualhosts, é necessário passar o cabeçalho do host para ab. ab -n 1000 -c 100 -H 'Host: mysite.com' http://127.0.0.1/Dito isto - a diferença entre resultados em cache (verniz) e não armazenados em cache é suficiente para validar a posição de que o problema não está relacionado à rede, ao DNS, etc. e está no processamento, conforme o esperado.
cyberx86

Respostas:

24

Em primeiro lugar, isso não é uma resposta, mas uma abordagem de diagnóstico.

Isso não é de forma alguma abrangente - ou mesmo algo próximo, é apenas um ponto de partida.

Hora do primeiro byte

O tempo até o primeiro byte (TTFB) possui vários componentes:

  • Pesquisa de DNS: encontre o endereço IP do domínio (possível melhoria: mais servidores DNS distribuídos / responsivos)
  • Tempo de conexão: abra um soquete para o servidor, negocie a conexão (o valor típico deve ser em torno do tempo 'ping' - geralmente é necessário um ida e volta - o keepalive deve ajudar nas solicitações subsequentes)
  • Aguardando: o processamento inicial necessário antes que o primeiro byte possa ser enviado (o local onde deve estar sua melhoria - será mais significativo para o conteúdo dinâmico.

Quando você olha para uma saída do ApacheBench, também vê:

  • Processamento: é a soma da espera + transferência completa do conteúdo (se o tempo de transferência for significativamente maior do que o esperado para baixar a quantidade de dados recebidos, ocorrerá um processamento adicional (após o primeiro byte recebido) (por exemplo, a página é liberando o conteúdo conforme disponível)

Comparações para eliminar componentes

Com poucas exceções, seu problema está no processamento de back-end, que geralmente se resume a código excessivamente complexo / ineficiente ou MySQL mal configurado.

Uma boa maneira de abordar esse problema é através de uma série de comparações que eliminam vários aspectos da sua instalação. Uma boa comparação deve manter-se o mais constante possível para ajudar a diminuir o problema. Atualmente, você forneceu as seguintes comparações:

  1. Site idêntico (clonado) em execução no servidor antigo e no novo servidor:
    • Diferença: Servidor
    • Resultado: o servidor antigo é rápido; novo servidor está lento
    • Notas: O que você precisa aqui é quantificar as diferenças entre esses servidores - tanto em termos da pilha usada (Nginx, etc) quanto do hardware (o servidor antigo é mais rápido porque é uma máquina mais poderosa?)
    • Conclusão: o código pode ser executado rapidamente na configuração correta
  2. Site de teste x site completo no novo servidor
    • Diferença: conteúdo, temas, plugins, etc
    • Resultado: o site de teste é rápido, o site completo é lento
    • Notas: em teoria, esse teste deve ajudá-lo a eliminar muitos aspectos da sua configuração - DNS, rede, até mesmo a sua configuração nginx / php / mysql - no entanto, não é muito "justo".
    • Conclusão: o conteúdo extra está tendo um impacto significativo no desempenho

O teste ideal faria você duplicar seu site completo, mas excluir todo o conteúdo, exceto um artigo e os comentários associados. O objetivo deste teste seria determinar conclusivamente se a grande quantidade de conteúdo é o problema ou se outros aspectos de sua configuração (plugins wordpress, tema, etc.) são a causa. Você compararia essencialmente o desempenho de sites idênticos, no mesmo servidor (novo) - carregando a mesma página (mesmo comprimento etc.) - com a única diferença no conteúdo total do site (por exemplo, há uma boa chance de que algum plug-in não dimensionar bem com o aumento do conteúdo).

Sem alterar nada, existem outras comparações que você pode fazer:

  • Teste de um local remoto versus local - isso ajudará a identificar se a rede, latência, DNS, etc. é a causa
    • Você já (um pouco) fez isso e principalmente concluiu que não tem um problema de rede.
  • Teste via Varnish (porta 80) vs nginx diretamente (porta 8080) - tente não alterar sua configuração entre os testes - use a porta correta. Isso mostrará o impacto do verniz. Como o Varnish é uma camada de armazenamento em cache, ele deve atender a todas as solicitações após a primeira muito rapidamente - essencialmente, deve ignorar o back-end e o processamento necessário para gerar uma página dinâmica e servir a cópia em cache muito rapidamente.
    • Você fez isso (embora não localmente) e demonstrou que o verniz tem um impacto positivo significativo no seu desempenho.

Ajustando seu back-end

A essa altura, você já deve ter encontrado o problema ou concluído que está no seu back-end. Isso deixa você Nginx, PHP ou MySQL.

(Devo mencionar aqui, que é sempre útil saber se o seu gargalo é CPU, RAM, ou I / O - entre sar, top, iostat, vmstat, free., Etc você deve ser capaz de chegar a alguma conclusão sobre isso)

Nginx

O Nginx está apenas recebendo solicitações e servindo conteúdo estático ou transferindo as solicitações para PHP-FPM - geralmente não há muito o que otimizar com o Nginx.

  • Definir trabalhadores = # núcleos da CPU
  • Ativar keepalive (um valor entre 10 e 15 é bom)
  • Desativar registro desnecessário
  • Aumente o tamanho do buffer, se necessário
  • Evite as instruções if (use nomes estáticos em vez de expressões regulares sempre que possível, elimine extensões desnecessárias)

Idealmente, o seu blog de teste e o blog clonado têm configurações idênticas; nesse caso, você efetivamente eliminou o Nginx como o problema.

Inscrição

No caso em que você está tentando identificar um problema no seu código (por exemplo, um plug-in lento, etc.), os logs lentos são o ponto de partida.

  • Habilite o log lento do MySQL e o log lento do PHP-FPM execute seu benchmark e veja o que está acontecendo como lento.

MySQL

  • Aumente seus caches e execute mysqltuner.pl para obter um bom ponto de partida.

PHP

  • desativar extensões desnecessárias,
  • desabilite register_globals, magic_quotes_ *, expose_php, register_argc_argv, always_populate_raw_post_data
  • aumentar o memory_limit
  • open_basedir e safe_mode têm implicações significativas de desempenho, mas também podem fornecer uma camada adicional de defesa. Teste com e sem eles, para determinar se o impacto no desempenho é tolerável.

PHP-FPM

  • Ajuste os valores pm. * - aumente-os para lidar com alta carga

Vale ressaltar que os resultados de seu htop mostram php-fpm consumindo a maior parte da CPU - e seu problema parece estar diretamente relacionado a isso.

Armazenamento em cache

Depois de otimizar cada provável gargalo, inicie o cache.

  • Você já possui um cache opCode (APC) - verifique se ele está funcionando (vem com um arquivo de teste) - verifique as taxas de acertos do cache e, se possível, tenha o cache do APC na memória em vez de no disco.
  • Configure seu código para armazenar em cache (por exemplo, usando um plugin para Wordpress, como o W3TC)
  • Com o nginx, você pode configurar o cache do FastCGI - mas como você tem o Varnish, é melhor evitar isso.
  • Configure uma camada de armazenamento em cache, como o Varnish (que você já fez) - e garanta que ela esteja funcionando (por exemplo, use varnishstat, leia Alcançando um alto Hitrate )
  • Adicione mais cache aos componentes do seu site - por exemplo, MemCached, se aplicável

Às vezes, dadas as limitações de seu aplicativo e hardware, talvez você não consiga melhorar o desempenho do back-end - no entanto, esse é o ponto do cache - para minimizar o uso do back-end.

Leitura adicional

cyberx86
fonte
2
Esse é um resumo fantástico de pontos a serem analisados. Muito obrigado pelo comentário, vou tentar realizar um teste pesado com todas essas sugestões - algumas delas, como você disse, já estão claras - e ver se consigo finalmente detectar o problema. Atenciosamente, cyberx86.
Javipas
Sobre o memory_limit, foi apontado em outro post que não ajuda no desempenho.
Forloop 31/10/2015