Lunghi tempi di attesa prima della risposta del server Apache 2.2 (Gentoo LAMP)


9

Di recente ho spostato il sito Web di un client (usando il CMS concrete5) su un VPS con Gentoo, Apache 2.2, PHP5 e MySQL 5 e ho notato che i tempi di risposta di Apache sono piuttosto scadenti (era lo stesso sul vecchio server) , a volte fino a 8-9 secondi, ma più spesso tra 300 ms e 3 secondi (verso 300 ms non mi dispiace). So che non è la latenza di rete, poiché il server ha un ping (dalla mia posizione) di circa 30 ms.

Ecco un esempio delle volte (puoi vedere che è scattante dopo l'attesa iniziale):

Cronologia del pannello Rete Firebug

Sto eseguendo APC (anche se non sono sicuro che funzioni bene ...) e SuExec. I moduli Apache sono:

 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 i moduli PHP sono:

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

Ho gzip abilitato su tutti i file rilevanti.

Apache è in esecuzione usando prefork e le impostazioni in httpd.conf sono:

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

HostnameLookups Off

Ho notato che le pagine che (penso) sono ricche di database, come il Dashboard del CMS, sono generalmente più lente. Pensavo che ciò potesse significare che MySQL poteva essere ottimizzato. Mi chiedevo anche sui moduli Apache - mi confondo tra mod_php5, mod_cgi, mod_fastcgi ecc ecc. - Esistono consigli contrastanti su tutta la rete per quanto riguarda il migliore da usare.

Ecco l'output di 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)

Ho notato quando è stata caricata una pagina pesante di DB, l'utilizzo della CPU è aumentato del 57% (usando la parte superiore) - per me suggerisce che ci sono alcune cose MySQL mal ottimizzate o la memorizzazione nella cache è assolutamente necessaria per accelerare questa configurazione.

Qualsiasi aiuto sarebbe molto apprezzato!


2
Solo un pensiero: HostnameLookupla configurazione del registro è abilitata? In tal caso, la ricerca DNS del client richiedente da aggiungere al registro di accesso potrebbe essere molto lenta (o addirittura il timeout del primo server DNS) può rallentare la richiesta completa.
jCoder,

È disabilitato - lo aggiungerò al post originale
melat0nin

Se sono solo richieste che coinvolgono PHP. Verifica la frammentazione in APC. È inoltre necessario monitorare attentamente l'utilizzo delle risorse; Il server utilizza tutte le sue risorse o è inattivo?
Kvisle,

Già (vedi OP) :)
melat0nin

Mi dispiace :): aggiornato il mio commento; Hai verificato se sono solo richieste PHP o anche altre richieste? Il server è inattivo o occupato? APC è frammentato o no? Quanta memoria viene "memorizzata nella cache" rispetto ad altre cose?
Kvisle,

Risposte:


14

Sai esattamente a cosa si stanno aggrappando i processi di lavoro di Apache? Prova questo per vedere:

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

Carica alcune nuove pagine (cioè non memorizzate nella cache locale) nel tuo browser, CTRL + C per interrompere strace, quindi ordina i strace.logs in base al tempo impiegato per ogni chiamata:

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

Visualizza eventuali strace.logs con chiamate di oltre 1,0 secondi e cerca per tempo dall'output del comando precedente. Questo ti indicherà il passo esatto su cui vengono appesi.

Per caso hai installato un firewall come CSF? Ho visto lo stesso problema su un VPS. Durante il debug dei processi httpd con strace ci volevano fino a 5 secondi o più per le chiamate gettimeofday. Stranamente l'ho ridotto a CSF, che stava cercando di filtrare l'interfaccia venet0, un'interfaccia loopback in container OpenVZ o Virtuozzo. L'impostazione di questo parametro in /etc/csf/csf.conf l'ha risolto principalmente per me:

"ETH_DEVICE_SKIP = "venet0,lo"

Dico principalmente perché a volte ci sono ancora 500-1000 ms in attesa che vengano stabilite le connessioni, ma è un grande miglioramento rispetto a 5000+.


1
Grazie per la tua risposta! Alla fine le cose sembravano essere ordinate quando l'APC funzionava correttamente - il sito ora è piuttosto scattante. +1 per istruzioni eccellenti, e le annoterò nel caso in cui mi imbattessi di nuovo in qualcosa del genere.
melat0nin

3

Ecco un'eccellente guida / procedura dettagliata per la risoluzione di questo tipo di problemi utilizzando strace.

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

Questa deve essere una scatola VPS di fascia bassa?

  • Potresti voler comporre le tue impostazioni di MySQL
  • Ottimizza Apache per ridurre il numero di fork httpd
  • Controlla se puoi abilitare lo scambio
  • APC è impostato per memorizzare automaticamente nella cache i codici operativi? Controlla usando lo script 'apc.php' distribuito con apc.

3

Devi separare network, apache, mysql e php come fonti della latenza.

Se riesci a estrarre rapidamente un'immagine da Apache (tempo molto basso al primo byte), la rete e Apache di solito vanno bene.

Se riesci a tirare una pagina con solo un'istruzione phpinfo (), allora normalmente PHP è ok (potrebbe essere necessario apportare alcune modifiche).

Se scrivi un semplice test di connessione DB ed è veloce, anche quel livello è di solito ok.

Infine, tira la pagina dell'applicazione. Se è lento, il problema è interno all'elaborazione delle applicazioni. Mentre l'accordatura può aiutare, questo è molto più difficile da risolvere.

Senza profilare l'applicazione, può essere difficile trovare il problema. Strumenti come NewRelic possono aiutare con questo problema, ma non è una cura.

La tua app ha qualche tipo di debug interno per mostrare dove viene trascorso il tempo?


0

suggerisco di aggiungere una misurazione del tempo di rendering e di verificare quanto tempo impiega il server per eseguire il rendering della pagina HTML pura. Quindi sai se si trova nel CMS o altrove. Scommetto che il mio 2 cent non è la configurazione del tuo server. / Maddin


Puoi suggerire un metodo per misurare il tempo di rendering? Il pannello Net di Firebug su una pagina HTML statica è sufficiente?
melat0nin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.