Nginx + php-fpm - Ogni php-fpm elabora il 70-100% di CPU durante l'esecuzione


8

Ho una situazione in cui si sta verificando quanto segue:

  • Siamo su linode con 8 core, 8 GB di RAM, 2,6 ghz - usando nginx + php-fpm - stiamo ottenendo grafici estremamente alti di utilizzo della CPU (che non vogliamo essere un vicino VPS così cattivo) ...

  • Abbiamo circa meno di 100 utenti alla volta sul sito - quindi questa situazione è anche incredibilmente imbarazzante - che il nostro utilizzo della CPU è molto elevato.

  • Stiamo usando un framework php-saggio, discutibilmente orribile molto sconosciuto, forse cpu invece di altri framework ben noti, ben documentati e ben realizzati come wordpress o drupal in cui c'è MOLTA documentazione sulla cache (così come i plugin che gestiscono la memorizzazione nella cache) php su una piattaforma nginx + php_fpm.

  • Quindi, abbiamo circa 6 processi php-fpm aperti che durante l'esecuzione, consumano individualmente GRANDI (30+, e spesso vicino al 99%) quantità di CPU - e non ho davvero la minima idea di come impedire loro di usare così tanto CPU . Non posso dire quali script php stanno causando questi picchi perché si verificano continuamente ... di solito solo 1 o 2 sono in esecuzione - ma quando tutti e 6 eseguono massimizziamo tutti gli 8 cpus.

  • Il mio file pool.d / www.conf ha le seguenti impostazioni:

    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 4
    pm.min_spare_servers = 2
    pm.max_spare_servers = 6
    
  • Abbiamo fatto questo ^ setup perché, nel modo in cui lo sto interpretando, la nostra memoria è davvero incredibile (htop mostra 472/7000 + mb usati, nessuno scambio ecc.) E potremmo gestire molti più processi e spezzare la linea in attesa di ottenere elaborati - MA sfortunatamente, poiché ogni processo è troppo intenso sulla nostra CPU durante l'esecuzione - finiamo per guidare la nostra CPU attraverso il tetto - quindi non possiamo gestire abbastanza processi.

  • La domanda : cosa possiamo fare per ridurre l'utilizzo del processo php-fpm cpu in modo da poter aumentare le impostazioni in quel file di configurazione del pool per php-fpm - e anche sì, il /var/log/php5-fpm.log ci sta urlando per aumentare i nostri figli e regolare / aumentare i nostri server min / max / start. Ma farlo fa impazzire il nostro carico come precedentemente indicato. Come possiamo farlo senza necessariamente utilizzare una cache o quali sono le nostre opzioni?

  • La mia idea? Ho letto cose sull'uso di cpulimit per assicurarmi che nessun processo richieda più di una quantità assegnata di cpu - ma ciò rallenterà le cose per renderle inutilizzabili? O così facendo potremmo aumentare la nostra capacità di eseguire più di alcuni processi - ho anche pensato di gestire due pool - uno per il nostro sito Web rivolto in avanti (ciò che i clienti sperimentano) e un altro per un backend (che sta influenzando il nostro sito rivolto in avanti quando il tempo -consuming report in corso).

  • Ho trascorso alcuni giorni a cercare, cercare su Google, ecc. Su questo argomento - ed è difficile perché la situazione di tutti è così unica per il loro sistema - il problema è trovarsi in un quadro così inaudito, forse scarsamente scritto - sta facendo è difficile trovare una soluzione. Non possiamo ancora eliminare questo framework: devo trovare una soluzione di qualche tipo.


AGGIORNAMENTO: ho implementato memcache per archiviare sessioni php - perché il framework si basa fortemente sulle sessioni utente e la natura del nostro sistema è che i dipendenti usano spesso più schede alla volta - ognuna delle quali torna alle sessioni per confermare abilità / dati utente / ecc. ... quindi spero di vedere un aumento delle prestazioni da questo - benvenuti a commentare questo, se lo desideri - vedrò come andrà domani quando supereremo le nostre ore di punta di volume più alto.


Nginx non è molto buono per un'applicazione web ad alta intensità di CPU - ma la nostra CPU alta è pessima - davvero pessima - e stiamo lavorando per risolverlo. Non ci sono grandi client di configurazione da avere perché DOVREBBE essere in grado di supportare un numero decente di client, ma l'elevato utilizzo della CPU per processo distorce tale capacità. Siamo passati ad apache solo perché fa MOLTO meglio con un elevato utilizzo della CPU - ma alla fine questo problema è più indicativo di un problema di app Web e potrebbe richiedere del tempo per risolverlo, ma non c'è tempo come il presente per iniziare a risolverlo.
amurrell,

Quando vai dal dottore e ti dice di prendere alcune medicine - perché sa che non ascolterai le dichiarazioni "smetti di bere soda e mangia fast food" - questo è esattamente il motivo per cui non c'era una grande risposta per me - perché la verità è che , nessuna installazione o correzione rapida è stata applicata, solo la triste verità che dobbiamo modificare drasticamente la nostra stessa app web.
amurrell,

Fortunatamente se hai questo problema con un framework popolare, potresti avere la possibilità di sfruttare la memorizzazione nella cache e la documentazione abbondante su di esso - ma siamo su qualche cosa oscura e casuale che non possiamo cambiare tranne il framework stesso. Sìì!
amurrell,

1
Quindi, da quello che ho capito, opcache sta memorizzando il tuo codice PHP come binario e può essere consumato da php-fpm molto più velocemente (memorizzazione nella cache) ma dovresti anche utilizzare la cache degli oggetti .. un esempio è la memorizzazione di un intero output di pagina come un "oggetto "in qualcosa come memcached. Questo in realtà memorizzerebbe nella cache l'output della pagina (o altre cose che vuoi come le sessioni php ecc.) ... Successivamente, potresti anche usare la vernice che è un proxy inverso - ma fondamentalmente è un intermediario tra la richiesta e il tuo server in modo che il tuo il server non viene colpito direttamente con le richieste e funziona dalla memoria per servire gli URL memorizzati nella cache.
amurrell,

1
Varnish è fantastico per questo - memorizzare una copia cache di ciò che ha ottenuto dal server in memoria - quindi la vernice prende gran parte del carico. Il mio attuale datore di lavoro è su nginx e usiamo vernice e memcached. Fortunatamente il framework in cui ci troviamo ora ha il proprio meccanismo di memorizzazione nella cache per determinare la cache della pagina (dati di pagina in uscita). Nel mio ultimo lavoro ho dovuto scriverlo nel framework da solo - non è stato divertente, ma ha funzionato. Apache - Non tornerei indietro, a meno che tu non abbia il tempo di riparare nginx .. Odiavo tornare indietro ma era il unica soluzione per non uccidere totalmente il nostro progetto mentre scrivevo il meccanismo di memorizzazione nella cache.
amurrell,

Risposte:


6

Un paio di cose da considerare (scusate in anticipo se le avete già considerate): prima di tutto, assicuratevi di ottimizzare la vostra configurazione nginx e invocare php-fpm solo quando assolutamente necessario. L'ultima cosa che vuoi fare è lasciare che php gestisca cose come pagine HTML statiche (cosa che farà felicemente).

In secondo luogo, dal momento che stai usando php-fpm, suggerisco di essere più aggressivo con il tempo di vita dei figli di php-fpm. Devi trovare il punto debole tra fili / bambini di breve durata e stabilità. I valori predefiniti di php-fpm sono troppo generosi per qualsiasi sistema di produzione, IMHO. Più un lavoratore è autorizzato a soddisfare le richieste, più instabile diventerà. Esiste anche un rischio maggiore di perdite di memoria e se questo framework a cui fai riferimento presenta bug come loop infiniti, che potrebbero causare problemi con il carico della CPU, ciò non dovrebbe danneggiare.

Ridurrei il numero pm.max_requestsper i tuoi pool di produzione. Penso che il valore predefinito sia 200. Vorrei iniziare da 50 e vedere dove ti porta.

In caso contrario, puoi anche provare queste opzioni globali (AFAIK sono tutte disabilitate per impostazione predefinita):

emergency_restart_threshold 3
emergency_restart_interval 1m
process_control_timeout 5s

Cosa significa questo? Se 3 processi figlio PHP-FPM escono con SIGSEGV o SIGBUS (ovvero arresto anomalo) entro 1 minuto, PHP-FPM dovrebbe riavviarsi automaticamente. Il processo figlio attende 5 secondi per una reazione sui segnali del master.

Ecco una bella panoramica di tutte le opzioni di configurazione che ho citato qui, così come altre: http://myjeeva.com/php-fpm-configuration-101.html

Spero che questi suggerimenti ti possano aiutare! Ricorda di modificare e osservare, sfortunatamente non sembra esserci una regola empirica per tutto ciò, come hai osservato, ci sono troppe variabili che influenzano il comportamento e la stabilità di PHP.

Infine, la funzione di limitazione della CPU di cui hai chiesto informazioni è documentata qui , ma ricorrerei solo se esaurisci ogni altra opzione. Se scegli questo percorso, farei sicuramente attenzione alle possibili interazioni tra le modifiche di PHP-FPM e la tua configurazione limits.conf. A quel punto etckeeper potrebbe essere un vero toccasana ! :)

In bocca al lupo!

Rouben


Proverò a limitare il max_requests domani - Sembra che ogni processo che consentiamo voglia consumare la CPU, quindi questa potrebbe essere una buona idea. Stiamo utilizzando le soglie di riavvio di emergenza, ma i miei numeri erano leggermente più alti: proverò i tuoi e vedrò come vanno le cose. Grazie per la tua completezza - molto apprezzato. Volevi conoscere i tuoi pensieri sulla cache? Mi chiedo se l'utilizzo della memorizzazione nella cache php significhi che il framework dovrebbe essere adattato per gestirlo. Sono abbastanza nuovo con questo concetto.
amurrell,

3

Stai eseguendo la cache del codice operativo, giusto?

Era l'APC che era il punto di partenza qui, ma è stato un pezzo difettoso per un po 'di tempo, ed è stato sostituito da Zend Opcache , che ora fa parte di PHP dal 5.5 e ha un backport in PECL per 5.3 e 5.4.


Sono interessato a questo Zend OpCache - Siamo al 5.3 - Se potessi espandere questa risposta, lo apprezzerei davvero!
amurrell,

Avevamo xcache - ma ora ho optato per Zend Opcache e l'ho installato e confermato che è attivo e funzionante in phpinfo (). Ti farò sapere se la nostra performance è migliore di conseguenza incrociamo le dita
amurrell,

Ho dovuto disabilitare zend opcache per ora - tutto funzionava tranne qualsiasi file css o js generato da php dinamico. Ho provato a inserire nella blacklist quei file da opcache - ma o la blacklist non ha funzionato o non riesco a capire perché opcache stia causando a nginx errori 502 di gateway difettosi SOLO per quei file. Di cui ho bisogno per il modello e fanno parte del framework non valido. Nei registri nginx ho ricevuto tonnellate di readv non riuscite - 104 errori di connessione peer.
amurrell,
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.