Lo strano caso di Mr. Time To First Byte


14

Ho un server web su un Linode 1024 VPS basato su

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6 (con PHP-FPM, APC)
  • Vernice 3.0.2

E un paio di blog lì basati su WordPress 3.3.1. Uno di questi è un semplice blog, con la configurazione predefinita, il tema e solo il post "Hello World", per testare il server. L'altro è un blog clonato da altri server con quasi 10k post e oltre 10k commenti. Questo blog ha prodotto circa 5.000 pezzi unici al giorno.

Il server fornisce buoni numeri su un test ab per il blog di test , ma lo stesso test con il blog clonato è impossibile da fare: il test ab carica troppo il server e devo interrompere il processo, che comunque fa ab mostrare questo risultato davvero scarso .

L'htop mostra anche un carico "normale" durante il normale funzionamento , ma un grosso carico anormale durante il test ab.

Sta succedendo un'altra cosa strana (la più importante per me): il Time To First Byte è estremamente alto , ma dopo quello aspetto il sito si carica molto velocemente. Questo può essere facilmente testato con servizi come tools.pingdom.com, che danno questo risultato . Si prega di prestare attenzione a quella regione gialla che significa "Tempo di attesa".

Perché sta succedendo? Possibili idee:

  • Configurazione PHP-FPM errata
  • Il tempo di risposta del DNS Linode è terribile. Sciocchezze: il blog di test risolve bene DNS, TTFB è fantastico
  • Configurazione Nginx errata

Nel caso in cui qualcuno abbia bisogno di maggiori informazioni,


Penso che questo possa avere qualcosa a che fare con la if -fdirettiva che stai usando nel locationcontenitore nella configurazione di nginx. Sulla base di ciò che sto leggendo qui wiki.nginx.org/Pitfalls , ho la sensazione che -fstia facendo una ricerca inefficiente del file che potrebbe causare un problema Time To First Byte, specialmente se hai directory con un gran numero di File.
d34dh0r53,

1
Alcune considerazioni: a) quali sono le differenze rispetto al server originale da cui viene clonato il blog (ad es. Esegue lo stesso stack?) B) se puoi, esegui ab direttamente dal server usando localhost e la porta. Prova ad accedere tramite vernice e quindi ad accedere direttamente a nginx). c) Abilitare i log lenti MySQL e PHP-FPM. d) esegui mysqltuner.pl e vedi se riesci a migliorare le tue prestazioni MySQL (sarebbe la differenza più ovvia tra i blog o i plugin). e) La configurazione PHP-FPM che hai pubblicato non sembra essere quella utilizzata da nginx (/var/run/php5-fpm-tpnet.sock! = /var/run/php5-fpm-www-data.sock)
cyberx86,

1
Sicuramente un problema con PHP. Wordpress è molto lento. Avrai bisogno di un plug-in per la cache per ottenere un tempo di caricamento decente quando hai così tanto contenuto.
Martin Fjordvald,

2
Hai detto che 'puoi eseguire ab su localhost e ottenere 4k req / s' - a quale localhost (precedente / corrente) ti riferisci? Se quel valore proviene dal tuo attuale server - quello con il TTFB elevato - allora il tuo problema è diventato molto più interessante - dal momento che hai eliminato efficacemente PHP, MySQL e il tuo web server. TTFB include DNS, tempo di andata e ritorno e tempo di elaborazione. Un lungo TTFB è generalmente dovuto all'elaborazione (ad esempio PHP / MySQL). Il punto di eseguire direttamente ab contro nginx è eliminare gli altri componenti. Inoltre, Varnish, se impostato correttamente, dovrebbe bypassare il backend, fornendo un req / s molto elevato.
cyberx86,

1
I test di localhost non sembrano validi: in realtà non hai recuperato il tuo blog. Notare la differenza nelle dimensioni della pagina: 7500 byte quando si accede dal dominio, 151 byte dall'host locale. Poiché probabilmente hai più host virtuali, devi passare l'intestazione host su ab. ab -n 1000 -c 100 -H 'Host: mysite.com' http://127.0.0.1/Detto questo, la differenza tra i risultati memorizzati nella cache (Vernice) e quelli non memorizzati è sufficiente per convalidare la posizione in cui il problema non è correlato alla rete, DNS, ecc. E risiede nell'elaborazione, come previsto.
cyberx86,

Risposte:


24

Innanzitutto, questa non è una risposta, tanto quanto un approccio diagnostico.

Questo non è affatto completo - o anche qualcosa di vicino, è solo un punto di partenza.

Tempo di primo byte

Il tempo al primo byte (TTFB) ha un numero di componenti:

  • Ricerca DNS: trova l'indirizzo IP del dominio (possibile miglioramento: server DNS più numerosi / distribuiti / reattivi)
  • Tempo di connessione: aprire un socket al server, negoziare la connessione (il valore tipico dovrebbe essere intorno al tempo di "ping" - di solito è necessario un round trip - keepalive dovrebbe aiutare per le richieste successive)
  • In attesa: elaborazione iniziale richiesta prima che sia possibile inviare il primo byte (è qui che dovrebbe essere il miglioramento: sarà più significativo per il contenuto dinamico.

Quando guardi un output di ApacheBench, vedi anche:

  • Elaborazione: questa è la somma dell'attesa + trasferimento completo del contenuto (se il tempo di trasferimento è significativamente più lungo di quanto ci si aspetterebbe per scaricare la quantità di dati ricevuti, si sta verificando un'ulteriore elaborazione (dopo il primo byte ricevuto) (ad es. La pagina è svuotare il contenuto quando è disponibile)

Confronti per eliminare i componenti

Con poche eccezioni, il problema risiederà nell'elaborazione del back-end, che di solito si riduce a un codice eccessivamente complesso / inefficiente o MySQL mal configurato.

Un buon modo per affrontare questo problema è attraverso una serie di confronti che elimineranno vari aspetti della configurazione. Un buon confronto dovrebbe mantenere il più costante possibile per aiutare a restringere il problema. Attualmente, hai fornito i seguenti confronti:

  1. Sito identico (clonato) in esecuzione sul vecchio server e sul nuovo server:
    • Differenza: server
    • Risultato: il vecchio server è veloce; il nuovo server è lento
    • Note: ciò di cui hai bisogno è quantificare le differenze tra questi server, sia in termini di stack utilizzato (Nginx, ecc.) Sia in termini di hardware (il vecchio server è più veloce perché è una macchina più potente?)
    • Conclusione: il codice potrebbe essere in grado di funzionare rapidamente con la configurazione corretta
  2. Sito di prova vs sito completo sul nuovo server
    • Differenza: contenuto, temi, plugin, ecc
    • Risultato: il sito di test è veloce, il sito completo è lento
    • Note: in teoria, questo test dovrebbe aiutarti ad eliminare molti aspetti della tua configurazione - DNS, rete, persino la tua configurazione nginx / php / mysql - tuttavia, non è del tutto "equo".
    • Conclusione: il contenuto extra sta avendo un impatto significativo sulle prestazioni

Il test ideale dovrebbe duplicare l'intero sito, ma quindi eliminare tutto il contenuto tranne un articolo e i commenti associati. Il punto di questo test sarebbe determinare in modo definitivo se la grande quantità di contenuti è il problema o se la causa sono altri aspetti della tua configurazione (plugin di wordpress, tema, ecc.). Dovresti essenzialmente confrontare le prestazioni di siti identici, sullo stesso (nuovo) server - caricando la stessa pagina (stessa lunghezza, ecc.) - con l'unica differenza che è il contenuto totale del sito (ad esempio c'è una buona probabilità che alcuni plugin non lo facciano ridimensionare bene con maggiore contenuto).

Senza cambiare nulla, ci sono alcuni altri confronti che puoi fare:

  • Test da una posizione remota rispetto a locale: questo aiuterà a identificare se la causa è la rete, la latenza, il DNS, ecc
    • Lo hai già (in qualche modo) fatto e in gran parte concluso che non hai un problema di rete.
  • Prova via Vernice (es. Porta 80) vs nginx direttamente (porta 8080) - cerca di non cambiare la configurazione tra i test - usa semplicemente la porta corretta. Questo ti mostrerà l'impatto di Varnish. Poiché Varnish è un livello di memorizzazione nella cache, dovrebbe servire molto rapidamente tutte le richieste dopo la prima; in sostanza, dovrebbe bypassare il back-end e l'elaborazione necessari per generare una pagina dinamica e servire la copia cache molto rapidamente.
    • Lo hai fatto (anche se non localmente) e hai dimostrato che Varnish ha un impatto positivo significativo sulla tua performance.

Ottimizza il tuo backend

A questo punto avresti dovuto trovare il problema o concludere che si trova nel tuo backend. Questo ti lascia Nginx, PHP o MySQL.

(Devo dire qui, che è sempre utile sapere se il collo di bottiglia è CPU, RAM, o I / O - tra sar, top, iostat, vmstat, free., Ecc si dovrebbe essere in grado di venire a qualche conclusione su questo)

nginx

Nginx sta semplicemente accettando richieste e offrendo contenuto statico o spostando le richieste su PHP-FPM - di solito non c'è molto da ottimizzare con Nginx.

  • Imposta lavoratori = # core della CPU
  • Abilita keepalive (un valore di 10-15 è buono)
  • Disabilita la registrazione non necessaria
  • Aumentare le dimensioni del buffer, se necessario
  • Evita le istruzioni if ​​(usa nomi statici anziché regex ove possibile, elimina le estensioni non necessarie)

Idealmente, il tuo blog di test e il tuo blog clonato hanno configurazioni identiche, nel qual caso hai eliminato Nginx in modo efficace come problema.

Applicazione

Nel caso in cui si stia tentando di identificare un problema nel codice (ad esempio un plugin lento, ecc.), I registri lenti sono il punto di partenza.

  • Abilita il log lento MySQL e il log lento PHP-FPM eseguono il tuo benchmark e vedi che cosa sta arrivando come lento.

MySQL

  • Aumenta le tue cache ed esegui mysqltuner.pl per ottenere un buon punto di partenza.

PHP

  • disabilitare le estensioni non necessarie,
  • disabilita register_globals, magic_quotes_ *, expose_php, register_argc_argv, always_populate_raw_post_data
  • aumenta il limite di memoria
  • open_basedir e safe_mode hanno implicazioni significative in termini di prestazioni, ma possono anche fornire un ulteriore livello di difesa. Prova con e senza di loro, per determinare se il loro impatto sulle prestazioni è tollerabile.

PHP-FPM

  • Regola i valori pm. *: Aumentali per gestire carichi elevati

Vale la pena notare che i risultati di htop mostrano che php-fpm consuma la maggior parte della CPU e il tuo problema sembra essere direttamente correlato a questo.

caching

Dopo aver ottimizzato ogni probabile collo di bottiglia, inizia la memorizzazione nella cache.

  • Hai già una cache opCode (APC) - assicurati che funzioni (viene fornito con un file di prova) - controlla le percentuali di hit della cache e, se possibile, disponi di cache APC in memoria anziché su disco.
  • Configura il tuo codice nella cache (ad es. Usando un plugin per Wordpress come W3TC)
  • Con nginx puoi impostare la memorizzazione nella cache FastCGI, ma poiché hai Varnish, è meglio evitarlo.
  • Imposta un livello di memorizzazione nella cache, come Varnish (che hai già fatto) e assicurati che funzioni (ad es. Usa varnishstat, leggi Ottenere un alto nitrato )
  • Aggiungi più cache per i componenti del tuo sito, ad esempio MemCached, se applicabile

A volte, dati i limiti dell'applicazione e dell'hardware, potresti non essere in grado di migliorare le prestazioni del back-end in modo tale da ridurre al minimo l'utilizzo del back-end.

Ulteriori letture


2
Questo è un fantastico riassunto di punti da analizzare. Grazie mille per il commento, cercherò di eseguire un test pesante con tutti questi suggerimenti - alcuni di essi, come hai detto, sono già chiari - e vedere se riesco finalmente a rilevare il problema. Cordiali saluti, cyberx86.
javipas,

A proposito di memory_limit, è stato sottolineato in un altro post che non aiuta con le prestazioni.
mollare il
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.