Aller au contenu principal
PHP-FPM

PHP-FPM : pools, mémoire et lenteurs, ce qui se règle vraiment

PHP-FPM remplace un module serveur par un gestionnaire de processus : un maître, des travailleurs, et un pool par site. Mal réglé, il renvoie des 502 sans explication ; bien réglé, il absorbe les pics et montre où le temps passe. Ce site décrit les paramètres qui comptent, le calcul de mémoire qui évite la saturation, et les journaux qui disent la vérité.

Ce que PHP-FPM change par rapport à un module serveur

Avec un module greffé au serveur web, chaque requête PHP occupe un processus du serveur : une requête lente bloque un emplacement pour tout le monde. PHP-FPM sépare les deux : le serveur web transmet la requête à un gestionnaire de processus, qui la confie à un travailleur disponible.

Le gestionnaire (le maître) ne sert aucune page : il démarre, surveille et recycle les travailleurs selon la configuration d'un pool. Cette séparation permet de limiter la mémoire, de redémarrer PHP sans toucher au serveur web, et d'attribuer à chaque site son propre utilisateur système.

Conséquence pratique : les erreurs ne se lisent plus au même endroit. Un 502 ne vient pas de PHP mais du serveur web qui n'a pas trouvé de travailleur disponible ; la cause est dans la configuration du pool ou dans la saturation mémoire, pas dans le code.

Les pools : un maître, des travailleurs, un utilisateur par site

Un pool est un ensemble de travailleurs qui partagent un utilisateur système, un socket d'écoute et des limites. Un pool par site est la règle : il isole les fichiers, permet de plafonner la mémoire d'un site sans pénaliser les autres, et empêche qu'un pic sur l'un vide la file de tous.

Le socket compte autant que les limites : un socket Unix, protégé par les droits du système de fichiers, évite d'exposer PHP sur le réseau. Un socket TCP sur l'adresse locale fonctionne aussi, mais s'ouvre à tout processus local qui sait le joindre.

Chaque pool peut avoir son propre fichier de journaux, son propre utilisateur et son propre groupe. C'est ce qui rend lisible un incident : le journal d'erreurs d'un pool ne contient que les erreurs du site concerné.

pm.max_children : le calcul qui évite le 502

Le paramètre décisif est le nombre maximal de travailleurs simultanés. Trop bas, les requêtes attendent puis le serveur web rend un 502 ; trop haut, la machine échange sur disque et tout ralentit, y compris les requêtes qui allaient vite.

Le calcul part de la mémoire réellement consommée par un travailleur, pas de la mémoire allouée à PHP. Un travailleur qui traite une page peut occuper plusieurs dizaines de mégaoctets : la mémoire disponible divisée par cette valeur donne le plafond, en réservant la part du système, de la base de données et du serveur web.

La mesure se fait sur la machine en charge, avec un outil de suivi de la mémoire par processus, pas au moment du pic. Un plafond calculé sur une machine neuve et appliqué sans contrôle se traduit par une saturation dès la première journée chargée.

static, dynamic, ondemand : trois comportements, trois usages

En mode static, le nombre de travailleurs est fixe : la mémoire est réservée en permanence et la réponse est immédiate. C'est le mode des sites à trafic régulier, quand la mémoire disponible est connue et suffisante.

En mode dynamic, les travailleurs naissent et meurent entre deux bornes : le minimum garantit la réactivité, le maximum protège la machine, et un intervalle d'inactivité décide du recyclage. C'est le compromis le plus courant pour plusieurs sites sur la même machine.

En mode ondemand, un travailleur ne démarre qu'à la première requête : la mémoire au repos est minimale, au prix d'une première réponse plus lente. Ce mode convient aux sites peu visités, pas à une boutique qui reçoit du trafic en continu.

Voir ce qui bloque : délais, journaux lents et page d'état

Un script sans limite de temps immobilise un travailleur jusqu'à la coupure du serveur web. Le paramètre de délai d'exécution du pool borne cette immobilisation : au-delà, le travailleur est arrêté et l'incident apparaît dans le journal au lieu de rester invisible.

Le journal des requêtes lentes enregistre la pile d'appel des scripts qui dépassent un seuil de durée. C'est la seule façon de distinguer un site qui reçoit beaucoup d'un site qui exécute mal : le premier se règle par la capacité, le second par le code.

La page d'état du pool, quand elle est activée et restreinte, donne en temps réel le nombre de travailleurs actifs, inactifs et en file d'attente. Sans elle, on devine ; avec elle, on voit si la file grossit avant que les utilisateurs ne le signalent.

Sécurité : cloisonner plutôt que filtrer

Un utilisateur système distinct par pool est la première barrière : un fichier déposé par une faille d'un site n'est pas lisible par les autres. Le compléter par une restriction des chemins accessibles empêche un script d'aller lire la configuration d'un voisin.

Les fonctions qui exécutent des commandes système ou ouvrent des fichiers distants se désactivent au niveau du pool, pas au niveau du code : la liste est ainsi la même pour tous les scripts du site, y compris ceux qu'on n'a pas écrits.

Enfin, l'affichage des erreurs se coupe en production et part dans un journal, avec les données sensibles masquées : un message d'erreur affiché peut révéler un chemin, un nom de base ou une requête, ce qui est exactement l'information recherchée par un attaquant.

Questions fréquentes

Pourquoi mon site renvoie-t-il des 502 ?

Le serveur web n'a pas trouvé de travailleur disponible : soit le plafond de travailleurs du pool est atteint, soit la machine manque de mémoire pour en démarrer un. La cause est dans la configuration du pool, pas dans le code PHP.

Comment calculer le nombre maximal de travailleurs ?

Mémoire disponible divisée par la mémoire réellement consommée par un travailleur, en réservant la part du système, de la base de données et du serveur web. La mesure se fait sur la machine en charge.

static, dynamic ou ondemand ?

static pour un trafic régulier avec de la mémoire disponible, dynamic pour plusieurs sites sur une même machine, ondemand pour un site peu visité où la mémoire au repos compte plus que la première réponse.

Comment savoir quel script ralentit le site ?

En activant le journal des requêtes lentes du pool : il enregistre la pile d'appel des scripts qui dépassent un seuil de durée, ce que le journal d'accès ne montre pas.

Faut-il un pool par site ?

Oui : chaque pool isole l'utilisateur système, les limites de mémoire et les journaux. Un incident sur un site ne vide alors pas la file d'attente des autres.

Les réglages par situation