Cosa c'è di sbagliato nella mia configurazione di php-fpm?


8

Ho un server a 64 bit ma solo 256 MB di RAM. Quindi, sono passato al server nginx con fast-cgi per connettermi a PHP. Ho PHP 5.3.6 in esecuzione.

Il problema è che dopo ogni due o tre giorni quando provo ad accedere a qualsiasi pagina PHP ricevo un errore interno del server. L'unico modo per aggirare è riavviare php-fpm manualmente. Ciò significa che avrei dovuto impostare alcuni parametri errati che lo stanno causando il soffocamento. Di seguito ho elencato le configurazioni rilevanti.

/etc/php-fpm.conf: -

include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0

/etc/php-fpm.d/www.conf: -

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

/etc/nginx/php.conf: -

location ~ \.php {
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        fastcgi_pass unix:---some-location---;
}

Aggiornamento 1

E ho quattro processi nginx in esecuzione. In media ogni processo php-fpm richiede 35 MB di RAM (dimensione della memoria virtuale 320 MB ciascuno). Ho anche un processo MySql in esecuzione.

Aggiornamento 2

Ho dimenticato di incollare i registri.

registro errori php-fpm: -

WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...

php-fpm www.error log: -

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137

Risposte:


17

Una raccomandazione fuori mano sarebbe quella di abbassare i valori impostati, probabilmente tagliandoli a metà.

Hai: pm.max_children = 10 Se dici 35 MB / processo = 350 MB; su una scatola da 256 MB che significa molto scambio o si esaurisce la memoria - nessuno dei due va bene.

Direi che prendi almeno 100 MB per altri processi, forse anche 150 MB per sicurezza, e poi dividi quel numero per 35 MB per ottenere i tuoi max_children. Mantieni tutti gli altri numeri in linea:

pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500

Ferma PHP-FPM ed esegui freeper avere un'idea della tua memoria disponibile: dividi per i tuoi 35 MB per ottenere i tuoi max_children.

A seconda della quantità di memoria di MySQL, potrebbe essere necessario portare max_children su 3.

Trovo che i processi PHP-FPM condividano molta memoria, faccio un rapido esperimento per determinare quanto viene realmente utilizzato. Arresta PHP-FPM ed esegui free. Avviare PHP-FPM visitare alcune pagine comuni (necessario poiché la memoria aumenta a seconda delle pagine caricate) e controllare la memoria totale utilizzata, sempre usando free- dividere la differenza per il numero di processi. Non è un sistema perfetto, ma trovo che sia abbastanza preciso (a volte neanche la colonna di dati in alto non è male).


Faccio una sosta freee inizio. Divido quella memoria libera per 35 per ottenere il max_children value. Non ho ottenuto lo scopo dell'ultimo paragrafo.
Apple è arrivato il

Sembra che posso supportare solo max 2.3 processi di PHP. : P Comunque ora devo max_children3.
AppleGrew

a) Lo scopo dell'ultimo paragrafo era quello di ottenere un valore più accurato per quanto consuma un processo PHP. Trovo che il valore da ps o top non corrisponda sempre al calo della memoria disponibile. Se trovi la memoria disponibile, esegui alcuni processi PHP, quindi rimisura la memoria disponibile (invece di guardare la memoria utilizzata dai processi) puoi ottenere un valore "alternativo" (e forse migliore) per la quantità di memoria utilizzata da ciascun processo. b) Anche il parametro memory_limit suggerito da invarbrass è un buon suggerimento. c) Dai un'occhiata allo script mysqltuner.pl, potrebbe essere d'aiuto con la tua configurazione del DB.
cyberx86,

@ cyberx86, quale valore freeprendi in considerazione? Quello della riga '- / + buffers / cache' che viene utilizzato per la cache del disco, ma in realtà gratuito per le app?
Roman Newaza,

@RomanNewaza - sì, vuoi guardare la memoria disponibile per l'applicazione, quindi userai la voce 'free' in '- / + buffers / cache'.
cyberx86,

6

La tua configurazione php-fpm sembra OK.

Ma il server che stai utilizzando è in qualche modo limitato dalle risorse. Dai log è evidente che i processi PHP stanno esaurendo la memoria disponibile.

Aggiungendo ai suggerimenti forniti da cyberx86:

Puoi provare a modificare il parametro memory_limit nel file php.ini (vedi qui ) (anche se non sono sicuro che farà molto bene)

Data la piccola quantità di memoria di sistema, penso che dovresti prendere seriamente in considerazione il passaggio al sistema operativo a 32 bit. L'uso di un sistema operativo x64 in realtà ti fa male piuttosto che essere utile.

Se non stai utilizzando l'archiviazione InnoDB nel tuo database MySql, puoi anche considerare di disattivare InnoDB nel tuo my.cnf: risparmierà altri 100 MB di RAM.

Lowendbox ha un ottimo tutorial su come ottimizzare i server per la configurazione di memoria insufficiente.


Beh, la mia voce è diventata rauca cercando di ragionare con la mia società di hosting per fornirmi un sistema operativo a 32 bit. Sembra che in tutta la rete queste compagnie forniscano solo 64 bit. Ho trovato solo un'azienda che fornisce un sistema operativo a 32 bit ma sono molto più costosi.
Apple è arrivato il

3

Un comando molto utile per trovare la memoria presa da php:

ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Quindi dividi la RAM che vuoi dedicare a php e hai il tuo valore max_children!

Inoltre, è possibile monitorare manualmente (è necessario impostare lo stato php dell'endpoint) o con Nagios.


awk: fatal: division by zero attempted
samayo,

1
Significa che non hai alcun processo php5-fpm .... devi cambiare il nome del processo "php5-fpm" per adattarlo al tuo.
Thomas Decaux,

Ho usato questo comando ps --no-headers -o "rss,cmd" | grep php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'In qualche modo le opzioni -C non funzionano.
morto il

Prova a eseguire il comando separatamente (intendo ps --no-headers -o "rss, cmd" prima ecc ...) dovrebbe essere facile eseguire il debug
Thomas Decaux
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.