Quel est le problème dans ma configuration php-fpm?

8

J'ai un serveur 64 bits mais seulement 256 Mo de RAM. Donc, je suis passé au serveur nginx avec fast-cgi pour me connecter à PHP. J'ai PHP 5.3.6 en cours d'exécution.

Le problème est qu'après tous les deux ou trois jours lorsque j'essaie d'accéder à n'importe quelle page PHP, j'obtiens une erreur interne du serveur. La seule solution consiste à redémarrer php-fpm manuellement. Cela signifie que j'aurais dû définir des paramètres incorrects, ce qui provoque son étranglement. Ci-dessous, j'ai énuméré les configs pertinentes.

/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---;
}

Mise à jour 1

Et j'ai quatre processus nginx en cours d'exécution. En moyenne, chaque processus php-fpm prend 35 Mo de RAM (taille de mémoire virtuelle 320 Mo chacun). J'ai également un processus MySql en cours d'exécution.

Update 2

J'ai oublié de coller les journaux.

journal des erreurs 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
AppleGrew
la source

Réponses:

17

Une recommandation directe serait de réduire vos valeurs définies - probablement de les réduire de moitié.

Vous avez: pm.max_children = 10 Si vous dites 35 Mo / processus = 350 Mo; sur une boîte de 256 Mo, ce qui signifie soit beaucoup d'échanges, soit vous manquez de mémoire - ni l'un ni l'autre n'est bon.

Je dirais que prendre au moins 100 Mo pour d'autres processus, peut-être même 150 Mo pour être sûr, puis diviser ce nombre par 35 Mo pour obtenir vos max_children. Gardez tous les autres numéros en ligne:

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

Arrêtez PHP-FPM et lancez-vous freepour avoir une idée de votre mémoire disponible - divisez par vos 35 Mo pour obtenir vos max_children.

Selon la quantité de mémoire prise par MySQL, vous devrez peut-être réduire max_children à 3.

Je trouve que les processus PHP-FPM partagent beaucoup de mémoire, faites une expérience rapide pour déterminer la quantité réellement utilisée. Arrêtez PHP-FPM et exécutez free. Démarrez PHP-FPM visitez quelques pages communes (nécessaires car la mémoire augmente en fonction des pages chargées), et vérifiez la mémoire totale utilisée, en utilisant à nouveau free- divisez la différence par le nombre de processus. Ce n'est pas un système parfait, mais je le trouve assez précis (parfois la colonne de données en haut n'est pas mauvaise non plus).

cyberx86
la source
Je fais un arrêt freeet je commence. Je divise cette mémoire libre par 35 pour obtenir le max_children value. Je n'ai pas compris l'objet du dernier paragraphe.
AppleGrew
Il semble que je ne puisse prendre en charge que 2,3 processus PHP au maximum. : P Quoi qu'il en soit, je dois maintenant max_childrenà 3.
AppleGrew
a) Le «dernier para» avait pour but d'obtenir une valeur plus précise de la consommation d'un processus PHP. Je trouve que la valeur de ps ou top ne correspond pas toujours à la baisse de mémoire disponible. Si vous trouvez la mémoire disponible, exécutez quelques processus PHP, puis remesurez la mémoire disponible (au lieu de regarder la mémoire utilisée par les processus), vous pouvez obtenir une valeur `` alternative '' (et peut-être meilleure) pour la quantité de mémoire utilisée par chaque processus. b) Le paramètre memory_limit suggéré par invarbrass est également une bonne suggestion. c) Jetez un œil au script mysqltuner.pl, cela peut vous aider avec votre configuration DB.
cyberx86
@ cyberx86, quelle valeur freeprenez-vous en compte? Celui de la ligne '- / + buffers / cache' qui est utilisé pour le cache disque, mais en fait gratuit pour les applications?
Roman Newaza
@RomanNewaza - oui, vous voulez regarder la mémoire disponible pour l'application, vous utiliserez donc l'entrée «libre» sous «- / + tampons / cache».
cyberx86
6

Votre configuration php-fpm semble OK.

Mais le serveur que vous utilisez est quelque peu limité en ressources. Il est évident d'après les journaux que les processus PHP épuisent la mémoire disponible.

Ajout aux suggestions fournies par cyberx86:

Vous pouvez essayer d'éditer le paramètre memory_limit dans le fichier php.ini (voir ici ) (même si je ne suis pas sûr que cela fera beaucoup de bien)

Compte tenu de la petite quantité de mémoire système, je pense que vous devriez sérieusement envisager de passer à un système d'exploitation 32 bits. L'utilisation d'un système d'exploitation x64 vous fait du mal plutôt que d'être bénéfique.

Si vous n'utilisez pas le stockage InnoDB dans votre base de données MySql, vous pouvez également envisager de désactiver InnoDB dans votre my.cnf - cela économisera encore 100 Mo de RAM.

Lowendbox a un excellent tutoriel sur la façon d'optimiser les serveurs pour une configuration à faible mémoire.

invarbrass
la source
Eh bien ma voix est devenue rauque en essayant de raisonner avec ma société d'hébergement pour me fournir un système d'exploitation 32 bits. Il semble partout sur le net que ces sociétés ne fournissent que 64 bits. Je n'ai trouvé qu'une seule entreprise qui fournit un système d'exploitation 32 bits, mais ils sont beaucoup plus coûteux.
AppleGrew
3

Une commande très pratique pour trouver la mémoire prise par php:

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

Ensuite, vous divisez la RAM que vous souhaitez consacrer à php, et vous avez votre valeur max_children!

En outre, vous pouvez surveiller manuellement (vous devez configurer le statut php du point de terminaison) ou avec Nagios.

Thomas Decaux
la source
awk: fatal: division by zero attempted
samayo
1
Signifie que vous n'avez pas de processus php5-fpm .... vous devez changer le nom du processus "php5-fpm" pour l'adapter au vôtre.
Thomas Decaux
J'ai utilisé cette commande Les ps --no-headers -o "rss,cmd" | grep php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'options -C ne fonctionnent pas.
fin
Essayez d'exécuter la commande séparément (je veux dire ps --no-headers -o "rss, cmd" d'abord etc ...) cela devrait être facile à déboguer
Thomas Decaux