Come eseguire il debug di timeout di Apache?


14

Uso un'applicazione Web PHP su un server Apache 2.2 (Ubuntu Server 10.04, 8x2GHz, RAM 12Gb) utilizzando prefork. Ogni giorno Apache riceve circa 100k-200k richieste, di cui circa 100-200 raggiungono il limite di timeout (quindi circa uno su mille), praticamente tutte le altre richieste vengono soddisfatte ben al di sotto del timeout.

Cosa posso fare per scoprire perché questo accade? O è normale avere alcune piccole parti di tutte le richieste scadute?

Questo è quello che ho fatto finora:

Richiede tempo di risposta

Come si può vedere, ci sono pochissime richieste tra il limite di timeout e una richiesta più ragionevole. Attualmente il limite di timeout è impostato su 50 secondi, in precedenza era impostato su 300 ed era ancora la stessa situazione con alcuni timeout e quindi un enorme divario rispetto alle altre richieste.

Tutte le richieste che scadono sono AJAXrichieste, ma poi la stragrande maggioranza di esse lo sono, quindi forse è più una coincidenza. Il codice di ritorno di Apache è 200, ma il limite di timeout è chiaramente raggiunto. Provengono da una vasta gamma di IP diversi.

Ho esaminato le richieste che scadono e non c'è niente di speciale in esse, se faccio le stesse richieste che passano in meno di un secondo.

Ho provato a esaminare le diverse risorse per vedere se riesco a trovare la causa, ma senza fortuna. C'è sempre molta memoria libera (il minimo è di circa 3 GB liberi), il carico a volte arriva fino a 1,4 e l'utilizzo della CPU al 40%, ma molti dei timeout si verificano quando il carico e l'utilizzo della CPU sono bassi. La scrittura / lettura del disco è praticamente costante durante il giorno. Non ci sono voci nel log delle query lente di MySQL (impostato per registrare nulla al di sopra di 1 secondo), nessuna richiesta utilizza molte scritture / letture di database.

Richiedere tempo di risposta con caricamento del sistema / CPU

Il blu è l'utilizzo della CPU, che raggiunge il 40%, mentre il marrone è carico con il picco a 1,4. Quindi possiamo vedere che otteniamo timeout anche con un basso utilizzo / carico della CPU (i picchi di dieci secondi corrispondono bene all'utilizzo della CPU, ma questo è un altro problema, ho maggiori speranze di scoprire cosa potrebbe causare questi).

Non ci sono errori nel registro degli errori di Apache e non l'ho visto raggiungere più di 200 processi Apache attivi.

Impostazioni del server:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

Aggiornare:

Ho aggiornato a Ubuntu 12.04.1, per ogni evenienza, nessuna modifica. Ho aggiunto mod_reqtimeout con le impostazioni:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Ora quasi tutti i timeout si verificano a 10 secondi, uno o due a 20 secondi. Presumo che ciò significhi che la maggior parte delle volte sta ricevendo il corpo della richiesta che è problematico da ricevere? Il corpo della richiesta non dovrebbe mai essere più grande di qualche centinaio di byte. Ho monitorato il traffico di rete su una base per 1 secondo e non supera mai 1Mbit / se non vedo alcun rxerr o rxdorps, considerando che il server è su una linea da 1 Gbit / s non sembra l'HopelessN00b pubblicato su. Potrebbe essere solo un caso di cattive connessioni utente?

Per i picchi ogni ora (sembrano spostarsi un po ', nei grafici sopra sono 33 minuti dopo l'ora, ora sono 12 minuti passati), ho provato a vedere se c'è qualcosa che corre periodicamente ( crons ecc.) ma non ho trovato nulla. PHP Garbage Collection viene eseguito due volte ogni ora, ma non al momento dei picchi, tuttavia ho provato a disabilitarlo ma non fa alcuna differenza.

Ho usato dstat con --top-cpu e top per esaminare i processi al momento dei picchi e tutto ciò che si presenta è che Apache sta lavorando sodo per alcuni secondi, ma nessun altro processo sta usando una CPU significativa.

Ho creato un grafico ingrandito dei picchi: Tempo di risposta della richiesta ingrandito

A me sembra che Apache si interrompa per alcuni secondi e quindi lavori sodo per elaborare le richieste che sono arrivate durante l'arresto. Cosa potrebbe causare un arresto del genere o sto interpretando male?


1
Volevo postare con alcuni grafici sulle richieste, ma il mio rappresentante è troppo basso.
Leon,

Risposte:


4

La prima cosa che noto, guardando il tuo primo grafico, sembra che ci sia un rallentamento orario (che si verifica circa 40 minuti dopo l'ora) che potrebbe contribuire al problema. Dovresti dare un'occhiata ai programmatori di attività sul sistema operativo / database.

Sulla base dei dati che hai fornito, il mio prossimo passo sarà guardare alla frequenza dei tempi di risposta (numero di risposte sull'asse Y contro durata su X) ma includendo solo gli URL che mostrano il timeout (o preferibilmente un URL alla volta ). Su un sistema tipico ciò dovrebbe seguire una distribuzione normale o negativa - le richieste che stanno scadendo potrebbero semplicemente far parte della coda - nel qual caso devi concentrare i tuoi sforzi sulla messa a punto generale. OTOH se la distribuzione è bimodale, allora devi cercare la contesa da qualche parte nel tuo codice.


Grazie per la risposta. Sto esaminando cosa potrebbe causare i rallentamenti orari. Nel frattempo ho fatto un diagramma di frequenza dei dati che già ho. Questo è solo uno degli URL che ha un problema di timeout (ma gli altri sembrano molto simili): leela.kikora.no/apache_hist_show.png La quantità di timeout è molto ridotta rispetto a quella che richiede meno di 10 secondi, ma sembra come potrebbe non essere parte della coda. D'altra parte, potrebbe essere solo che dal momento che rappresentano qualcosa che avrebbe richiesto più di 50 secondi, dovrebbe apparire così.
Leon,

3

Ci ho pensato un altro, basandomi sul fatto che ricevi un gran numero di richieste al giorno e sembra che i timeout si verifichino solo nelle ore di punta (dalle foto che hai pubblicato).

C'è un post sul blog di Server Fault,Per Second Measurements Don't Cut It ... è possibile che alcune di queste richieste stiano riscontrando lo stesso problema che ha riscontrato il team ServerFault?

Abbiamo scoperto che stavamo scartando i pacchetti abbastanza frequentemente su interfacce da 1 Gbit / s a ​​velocità di soli 10-30 MBit / s che danneggiano le nostre prestazioni. Questo perché quella velocità di 10-30 MBit / s è in realtà il numero di bit trasferiti per 5 minuti convertiti in una frequenza di un secondo. Quando ci siamo avvicinati a Wireshark e abbiamo usato la grafica IO di un millisecondo, abbiamo visto che avremmo spesso fatto scoppiare la frequenza di 1 Mbit per millisecondo delle interfacce cosiddette 1 Gbit / s.


Interessante, lo darò un'occhiata. Ho abilitato mod_reqtimeout e l'ho impostato su header RequestReadTimeout = 20-40, minrate = 500 e RequestReadTimeout body = 10, minrate = 500 e quasi tutti i timeout avvengono ora a 10 secondi. Presumo che ciò significhi che il corpo della richiesta impiega troppo tempo (il corpo non dovrebbe mai essere più di qualche centinaio di byte al massimo), quindi alcuni dei miei utenti hanno connessioni errate o come dici tu c'è una congestione sul lato del mio server.
Leon,
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.