Table des matières de l'article :
PHP-FPM (ou Fast Process Manager) offre plusieurs avantages par rapport à mod_php, deux des plus notables étant plus flexibles à configurer et actuellement la méthode préférée d'exécution de PHP par de nombreux membres de la communauté. Cependant, si vous utilisez les paramètres de configuration par défaut de votre gestionnaire de packages, vous n'en tirerez probablement pas le meilleur parti.
Dans cet article, je vais donner un bref aperçu de la façon dont améliorer les performances de PHP-FPM en discutant des trois types de gestionnaires de processus PHP-FPM et lequel est le meilleur à utiliser dans quelles circonstances.
PHP-FPM peut utiliser l'un des trois types de gestion de processus :
- statique (statique)
- dynamique (dynamique)
- à la demande (sur demande)
Voyons un peu en détail ce que chacun représente en allant identifier les avantages et les inconvénients des trois modes différents qui peuvent tout de même cohabiter tranquillement sur un même serveur.
Par exemple, nous pourrions avoir trois sites Web sur le même serveur, dont un fonctionnant en mode statique, un à la demande et un dynamique sans aucune restriction et avec une séparation totale des privilèges.
PHP en mode statique
Statique garantit qu'un nombre fixe de processus enfants est toujours disponible pour gérer les demandes des utilisateurs. Ceci est réglé avec pm.max_enfants . Dans ce mode, les demandes n'ont pas à attendre que de nouveaux processus démarrent, ce qui en fait l'approche la plus rapide.
En supposant que vous souhaitiez utiliser une configuration statique avec 10 processus enfants toujours disponibles, vous devez le configurer /etc/php/7.2/fpm/pool.d/www.conf
(en supposant que vous utilisez le fichier de configuration PHP-FPM par défaut de Debian/Ubunut) comme suit :
pm = static pm.max_children = 10
Pour voir si le changement de configuration a été effectif, après avoir redémarré PHP-FPM, exécutez pstree -c -H <PHP-FPM process id> -S <PHP-FPM process id>
. Cela montrera qu'il y a dix processus disponibles, comme dans l'exemple ci-dessous.
php-fpm7.2-+-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 |-php-fpm7.2 `-php-fpm7.2
PHP en mode dynamique
Dans ce mode, PHP-FPM gère dynamiquement le nombre de processus enfants disponibles et s'assure que Au moins un processus enfant est toujours disponible.
Cette configuration utilise cinq options de configuration ; ceux-ci sont:
pm.max_children
: le nombre maximum de processus enfants pouvant être générés.pm.start_servers
: le nombre de processus enfants à lancer au démarrage de PHP-FPM.pm.min_spare_servers
: le nombre minimum de processus enfants inactifs que PHP-FPM créera. D'autres sont créés si moins que ce nombre sont disponibles.pm.max_spare_servers
: Le nombre maximum de processus enfants inactifs que PHP-FPM créera. S'il existe plusieurs processus enfants de cette valeur, certains seront supprimés.pm.process_idle_timeout
: le temps d'inactivité, en secondes, après lequel un processus enfant sera terminé.
Vient maintenant la partie amusante; comment calculez-vous les valeurs pour chaque paramètre? Sébastien Buckpesch , propose la formule suivante :
Réglage | Valeur |
---|---|
max_enfants | (RAM totale - Mémoire utilisée pour Linux, DB, etc.) / taille du processus |
serveur_démarrage | Nombre de cœurs de processeur x 4 |
min_spare_servers | Nombre de cœurs de processeur x 2 |
max_spare_servers | Égal àstart_servers |
Nous devons également mettre en place pm.process_idle_timeout
, qui est le nombre de secondes après lesquelles un processus inactif sera abandonné.
Disons que notre serveur a deux processeurs, chacun avec quatre cœurs et 8 Go de RAM. En supposant que Linux et ses démons utilisent environ 2 Go (utilisez free -hl
pour obtenir une valeur plus précise), cela nous laisse environ 6192 Mo.
Maintenant, combien de mémoire chaque processus utilise-t-il ? Pour calculer cela, il existe un script Python appelé ps_mem.py . Après l'avoir exécuté, en utilisant sudo python ps_mem.py | grep php-fpm
, vous obtiendrez une sortie semblable à celle-ci :
28.4 MiB + 33.8 MiB = 62.2 MiB php-fpm7.2 (11)
La première colonne est la mémoire privée. La deuxième colonne est la mémoire partagée. La troisième colonne est la RAM totale utilisée. La quatrième colonne est le nom du processus.
D'après ce qui précède, vous pouvez voir que la taille du processus est de 62,2 Mio. Ainsi, en mettant toutes ces informations dans notre formule, nous arrivons à ce qui suit :
# Round the result up. (8192 - 2000) / 62.2
Sur cette base, nous arrivons aux valeurs de réglage suivantes :
Réglage | Valeur |
---|---|
max_enfants | 100 |
serveur_démarrage | 32 |
min_spare_servers | 16 |
max_spare_servers | 32 |
Nous partirons pm.process_idle_timeout
le défaut de 10s
. En supposant que nous soyons satisfaits de ces paramètres, nous le configurerions comme suit :
pm = dynamic pm.max_children = 100 pm.start_servers = 32 pm.min_spare_servers = 16 pm.max_spare_servers = 32 pm.max_requests = 200
Vous pouvez également utiliser régulièrement des outils de surveillance de la mémoire pour surveiller la quantité de mémoire utilisée par votre application. Il existe un certain nombre d'options disponibles pour PHP, y compris php-memprof.
PHP en mode à la demande
La méthode ondemand lance les processus fork PHP-FPM lorsque les requêtes sont reçues. Pour configurer PHP-FPM en mode à la demande, vous devez définir les paramètres suivants :
pm.max_children
pm.process_idle_timeout
pm.max_requests
pm.max_requests
définit le nombre de requêtes que chaque processus enfant doit exécuter avant de réapparaître. La documentation suggère que ce paramètre est utile pour contourner les fuites de mémoire.
En supposant que vous utilisiez les mêmes paramètres que dynamic
, nous le configurerions comme suit :
pm = ondemand pm.max_children = 100 pm.process_idle_timeout = 10s pm.max_requests = 200
Quelle configuration vous convient ?
Franchement? La réponse est: " dépend ”, Comme cela dépend toujours du type d'applications que vous exécutez. Cependant, voici quelques conseils sur la configuration à choisir.
Site à faible trafic
Si vous avez un site à faible trafic, tel qu'un site qui héberge un panneau de contrôle principal, tel que cPanel , utilisez à la demande. La mémoire sera sauvegardée car les processus enfants ne seront générés que lorsqu'ils sont nécessaires et tués lorsqu'ils ne sont plus nécessaires. Puisqu'il s'agit d'un backend, les utilisateurs peuvent attendre un moment supplémentaire ou deux pendant qu'un thread est généré pour gérer leur demande.
Cependant, l'apparition d'un processus n'est pas "immédiate" et donc si vous essayez d'obtenir des performances maximales et de gagner ne serait-ce que quelques millisecondes, le mode à la demande est certainement le moins performant des trois disponibles.
Site à fort trafic
Si vous avez un site internet à fort trafic, il est conseillé d'utiliser le mode static
et ajustez les paramètres en fonction de vos besoins au fil du temps et des ressources matérielles disponibles. Il peut sembler écrasant d'avoir un grand nombre de processus enfants toujours prêts à recevoir des demandes, mais pour les sites à fort trafic, il est essentiel que les réponses soient rapides et immédiates.
Les sites à fort trafic doivent réagir le plus rapidement possible. Il est donc indispensable d’utiliser static
afin qu'un nombre suffisant de processus enfants soient toujours prêts à gérer les demandes entrantes. Cette approche garantit des temps de réponse rapides, améliorant l'expérience utilisateur et réduisant le risque de surcharge du serveur.
Utiliser le mode ondemand
, les processus enfants peuvent consommer trop de mémoire en raison de la génération et de l'arrêt continus, et le retard dans le démarrage des processus peut entraîner une dégradation significative des performances. Ce comportement est généralement inacceptable pour les sites à fort trafic, où chaque milliseconde compte.
Le mode dynamic
peut représenter un compromis, en fonction de votre configuration spécifique. Dans certains cas, il peut offrir des performances suffisantes, mais vous pouvez vous retrouver avec une configuration qui, en fait, reflète le mode static
. Le choix du mode dépend des caractéristiques spécifiques du site et des ressources disponibles, mais pour optimiser les performances des sites à fort trafic, static
cela reste souvent le meilleur choix.
Utilisation de plusieurs pools par frontend / backend
Maintenant, une dernière recommandation : servez le front-end et le back-end de votre site Web à l'aide de différentes piscines .
Supposons que vous ayez un site e-commerce, peut-être propulsé par Magento ou WooCommerce. Vous pouvez considérer l'application comme composée de deux parties :
- Une interface où les clients peuvent parcourir et effectuer des achats
- Un backend, où le personnel administratif gère le magasin (par exemple ajouter/supprimer des produits , catégories e Étiquette e revoir les notes )
Vu sous cet angle, il est logique d'avoir un pool servant le front-end et un autre servant le back-end et de les configurer de manière appropriée.
Pour ce que ça vaut, vous pouvez diviser n'importe quelle application en plusieurs parties en utilisant cette stratégie si cela a du sens. Voici comment procéder.
In /etc/php/7.2/fpm/pool.d/www.conf
, ajoutez la configuration suivante :
; frontend [frontend] listen = /var/run/php-fpm-frontend.sock user = www-data group = www-data listen.owner = www-data listen.group = www-data pm = static pm.max_children = 5
; backend [backend] listen = /var/run/php-fpm-backend.sock user = www-data group = www-data listen.owner = www-data listen.group = www-data pm = ondemand pm.max_children = 5 pm.process_idle_timeout = 10s
Cela crée deux pools, un pour le front-end et un pour le back-end. Ils ont tous les deux le même utilisateur et le même groupe, mais ont des configurations de gestionnaire de processus différentes et sont connectés via des sockets différents.
Le pool frontal utilise une configuration statique avec un petit nombre maximal de processus enfants. Le pool principal utilise la configuration à la demande, même avec un petit nombre de configurations. Ces nombres sont arbitraires, car ils le sont à titre d'exemple.
Avec cela enregistré, pour votre fichier NGINX vhost, vous pouvez par exemple utiliser la configuration suivante :
server { listen 80; server_name test-site.localdomain; root /var/www/test-site/public;
access_log /var/log/nginx/test-site.access.log; error_log /var/log/nginx/test-site.error.log error; index index.php;
set $fpm_socket "unix:/var/run/php-fpm-frontend.sock";
if ($uri ~* "^/api/") { set $fpm_socket "unix:/var/run/php-fpm-backend.sock"; }
location / { try_files $uri $uri/ /index.php;
location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_pass $fpm_socket; fastcgi_index index.php; include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } }
Cela crée une configuration d'hôte virtuel qui envoie des demandes au pool frontal ou principal, en fonction de l'emplacement demandé. Toutes les demandes /api
elles sont envoyées au pool principal et toutes les autres requêtes sont acheminées vers le serveur frontal.
Conclusions
Il s'agissait d'une introduction rapide à l'optimisation de PHP-FPM pour de meilleures performances. Nous avons examiné les trois configurations différentes du gestionnaire de processus, leurs paramètres et discuté du moment où chaque configuration a du sens. Nous avons ensuite fini par regarder les pools de travailleurs.
Nous pouvons brièvement résumer qu'en ce qui concerne PHP-FPM, une fois que vous commencez à traiter un trafic important, les gestionnaires de processus dynamiques et à la demande pour PHP-FPM peuvent limiter le débit en raison de la surcharge inhérente. Connaissez votre système et configurez vos processus PHP-FPM pour qu'ils correspondent à la capacité maximale de votre serveur. Commencer avecpm.max_children
définissez l'utilisation maximale de pm dynamic ou ondemand, puis augmentez jusqu'au point où la mémoire et le processeur peuvent traiter sans être surchargés. Vous remarquerez qu'avec pm static (puisque vous gardez tout en mémoire), les pics de trafic au fil du temps entraînent moins de pics de CPU et la charge de votre serveur et les moyennes de CPU seront plus fluides.
Mise à jour: Nous avons ajouté un tableau de comparaison de référence A / B. Avoir des processus PHP-FPM en mémoire améliore les performances au prix de l'utilisation de plus de mémoire pour les faire attendre.
Dans le cas où vous recherchez un réglage ponctuel et détaillé de l'interpréteur PHP, nous pouvons vous proposer ce service personnalisé pour optimiser au mieux les performances de votre site. Contactez-nous pour une consultation détaillée et découvrez comment nous pouvons vous aider à améliorer considérablement la vitesse et l’efficacité de votre environnement PHP.