Longos tempos de espera antes da resposta do servidor Apache 2.2 (Gentoo LAMP)

9

Recentemente, mudei o site de um cliente (usando o CMS Concrete5) para um VPS executando o Gentoo, Apache 2.2, PHP5 e MySQL 5 e notei que os tempos de resposta do Apache são muito ruins (era o mesmo no servidor antigo) , às vezes de 8 a 9 segundos, mas com mais frequência entre 300 ms e 3 segundos (em relação a 300 ms, não me importo). Eu sei que não é a latência da rede, pois o servidor tem um ping (da minha localização) de cerca de 30ms.

Aqui está um exemplo dos horários (você pode ver que é instável após a espera inicial):

Linha do tempo do painel Firebug Net

Estou executando o APC (embora não tenha certeza de que esteja funcionando corretamente ...) e o SuExec. Os módulos Apache são:

 core_module (static)
 authn_file_module (static)
 authn_default_module (static)
 authz_host_module (static)
 authz_groupfile_module (static)
 authz_user_module (static)
 authz_default_module (static)
 auth_basic_module (static)
 include_module (static)
 filter_module (static)
 deflate_module (static)
 log_config_module (static)
 env_module (static)
 expires_module (static)
 headers_module (static)
 setenvif_module (static)
 version_module (static)
 ssl_module (static)
 mpm_prefork_module (static)
 http_module (static)
 mime_module (static)
 status_module (static)
 autoindex_module (static)
 asis_module (static)
 info_module (static)
 suexec_module (static)
 cgi_module (static)
 negotiation_module (static)
 dir_module (static)
 actions_module (static)
 userdir_module (static)
 alias_module (static)
 rewrite_module (static)
 so_module (static)
 suphp_module (shared)

e módulos PHP são:

bcmath
calendar
ctype
curl
db
dbase
domxml
exif
ftp
gd
gettext
iconv
imap
mbstring
mcrypt
mime_magic
mysql
openssl
overload
pcre
posix
session
standard
sysvsem
sysvshm
tokenizer
xml
xslt
zlib

Eu tenho o gzip ativado em todos os arquivos relevantes.

O Apache está sendo executado usando prefork, e as configurações no httpd.conf são:

<IfModule prefork.c>
StartServers         10
MinSpareServers      10
MaxSpareServers      20
MaxClients           250
MaxRequestsPerChild  4000
</IfModule>

HostnameLookups Off

Percebi que as páginas que (acho) são pesadas em bancos de dados, como o Painel do CMS, geralmente são mais lentas. Eu pensei que isso poderia significar que o MySQL poderia ser otimizado. Também me perguntei sobre os módulos Apache - fico confuso entre mod_php5, mod_cgi, mod_fastcgi etc etc - há conselhos conflitantes em toda a rede sobre o melhor a ser usado.

Aqui está a saída do MySQLTuner :

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.0.44-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: -Archive -BDB -Federated -InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 35M (Tables: 161)
[!!] Total fragmented tables: 15

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 3d 21h 44m 16s (293K q [0.868 qps], 1K conn, TX: 135M, RX: 90M)
[--] Reads / Writes: 99% / 1%
[--] Total buffers: 58.0M global + 1.6M per thread (100 max threads)
[!!] Maximum possible memory usage: 219.7M (93% of installed RAM)
[OK] Slow queries: 0% (0/293K)
[OK] Highest usage of available connections: 2% (2/100)
[OK] Key buffer size / total MyISAM indexes: 16.0M/20.9M
[OK] Key buffer hit rate: 99.6% (5M cached / 21K reads)
[!!] Query cache is disabled
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 3K sorts)
[!!] Temporary tables created on disk: 47% (2K on disk / 5K total)
[!!] Thread cache is disabled
[!!] Table cache hit rate: 6% (64 open / 1K opened)
[OK] Open file limit used: 12% (128/1K)
[OK] Table locks acquired immediately: 100% (356K immediate / 356K locks)

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Reduce your overall MySQL memory footprint for system stability
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Set thread_cache_size to 4 as a starting value
    Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    query_cache_size (>= 8M)
    tmp_table_size (> 32M)
    max_heap_table_size (> 16M)
    thread_cache_size (start at 4)
    table_cache (> 64)

Percebi que quando uma página pesada em banco de dados foi carregada, o uso da CPU aumentou 57% (usando top) - para mim, isso sugere que há coisas MySQL mal otimizadas ou o cache é absolutamente necessário para acelerar essa configuração.

Qualquer ajuda seria muito apreciada!

melat0nin
fonte
2
Apenas um pensamento: HostnameLookupa configuração do log está ativada? Nesse caso, a pesquisa de DNS do cliente solicitante a ser adicionado ao log de acesso pode ser muito lenta (ou o primeiro servidor DNS atinge o tempo limite), o que pode atrasar a solicitação completa.
jCoder
Está desabilitado - vou adicioná-lo ao post original #
melat0nin 18/10/11
Se são apenas pedidos que envolvem PHP. Verifique se há fragmentação no APC. Você também deve monitorar de perto o uso de recursos; O servidor está utilizando todos os seus recursos ou está ocioso?
Kvisle
Já sou (ver OP) :)
melat0nin
Desculpe por isso :) - atualizei meu comentário; Você verificou se são apenas solicitações PHP ou outras solicitações também? O servidor está ocioso ou ocupado? A APC está fragmentada ou não? Quanta memória é 'armazenada em cache' versus outras coisas?
Kvisle

Respostas:

14

Você sabe exatamente no que os processos do Apache Worker estão sendo travados? Tente isto para ver:

mkdir /strace; ps auxw | grep httpd | awk '{print"-p " $2}' | xargs strace -o /strace/strace.log -ff -s4096 -r

Carregue algumas páginas novas (ou seja, não armazenadas em cache localmente) em seu navegador, CTRL + C para interromper o strace e classifique os strace.logs pelo tempo gasto em cada chamada:

for i in `ls /strace/*`; do echo $i; cat $i | cut -c11-17 | sort -rn | head; done

Veja qualquer strace.logs com mais de 1,0 segundo de chamadas e pesquise pela hora a partir da saída do comando anterior. Isso indicará o passo exato em que eles estão se pendurando.

Você, por mudança, possui um firewall como o CSF ​​instalado? Eu vi esse mesmo problema em um VPS. Ao depurar processos httpd com strace, levava até 5 segundos ou mais nas chamadas gettimeofday. Estranhamente, reduzi isso ao CSF, que estava tentando filtrar a interface venet0, uma interface de loopback em contêineres OpenVZ ou Virtuozzo. Definir este parâmetro no /etc/csf/csf.conf corrigiu-o principalmente para mim:

"ETH_DEVICE_SKIP = "venet0,lo"

Digo principalmente porque, às vezes, ainda há 500-1000ms de espera para estabelecer conexões, mas é uma grande melhoria em relação a 5000+.

reflexiv
fonte
1
Obrigado pela sua resposta! No final, as coisas pareciam ser resolvidas quando a APC funcionava corretamente - o site é bem rápido agora. +1 para obter instruções excelentes, e as anotarei caso eu me depare com algo assim novamente.
melat0nin
3

Aqui está uma excelente cartilha / explicação passo a passo para solucionar esses tipos de problemas usando o strace.

Maximum possible memory usage: 219.7M (93% of installed RAM)

Deve ser uma caixa VPS low-end?

  • Você pode querer discar suas configurações do MySQL
  • Ajuste o Apache para reduzir o número de garfos httpd
  • Verifique se você pode ativar a troca
  • O APC está configurado para armazenar em cache automaticamente os códigos de operação? Verifique usando o script 'apc.php' distribuído com o apc.
gelo fino
fonte
3

Você tem que separar rede, apache, mysql e php como fontes da latência.

Se você pode extrair uma imagem do apache rapidamente (tempo muito baixo para o primeiro byte), a rede e o apache geralmente ficam bem.

Se você pode puxar uma página com apenas uma instrução phpinfo (), normalmente o PHP está ok (pode precisar de alguns ajustes).

Se você escrever um teste simples de conexão com o banco de dados e for rápido, essa camada também estará ok.

Por fim, puxe a página do aplicativo. Se estiver lento, o problema é interno ao processamento dos aplicativos. Embora o ajuste possa ajudar, isso é muito mais difícil de resolver.

Sem criar um perfil do aplicativo, pode ser difícil encontrar o problema. Ferramentas como NewRelic podem ajudar com esse problema, mas não são uma cura.

Seu aplicativo tem algum tipo de depuração interna para mostrar onde o tempo está sendo gasto?

jeffatrackaid
fonte
0

Eu sugiro adicionar uma medição do tempo de renderização e verificar quanto tempo leva para o servidor renderizar a página HTML pura. Então você sabe se está no CMS ou em outro lugar. Aposto que meu 2cent não é sua configuração de servidor. / maddin

maddin
fonte
Você pode sugerir um método para medir o tempo de renderização? O painel Net do Firebug em uma página HTML estática é suficiente?
melat0nin