...

WordPress PHP-FPM Children : des valeurs erronées bloquent les pages

PHP-FPM Enfants décident dans WordPress si les demandes sont fluides ou si elles restent bloquées dans la file d'attente. Je montre comment de fausses pm.max_children-Les valeurs bloquent les pages, mangent la RAM et comment calculer des valeurs propres.

Points centraux

Avant d'aller plus loin, je vais résumer brièvement les messages clés :

  • pm.max_children détermine le nombre de requêtes PHP simultanées.
  • Trop peu Children génère des files d'attente, 502/504 et un TTFB élevé.
  • Trop entraîne des goulots d'étranglement de RAM, des swap et des OOM-kills.
  • Formule: RAM PHP disponible / taille du processus × 0,7-0,8.
  • Itératif Le tuning avec monitoring fournit la meilleure performance à long terme.

Pourquoi les faux PHP-FPM Children bloquent-ils les pages ?

Chaque requête dynamique de WordPress nécessite un Travailleur, Et c'est précisément ces processus que le pool contrôle via pm.max_children. Si je fixe une valeur trop basse, les demandes s'accumulent dans une file d'attente et les TTFB augmente sensiblement. Si je fixe une valeur trop élevée, chaque processus enfant utilise de la RAM supplémentaire et le serveur passe en swap. Dans le swap, tout ralentit jusqu'à ce qu'Apache ou Nginx signale 502/504 ou que le tueur d'OOM mette fin aux processus. Un débit sain n'est obtenu que lorsque le nombre d'enfants correspond au budget RAM réel et à la charge du projet.

La formule pour pm.max_children dans la pratique

Je commence avec une formule simple : la RAM disponible pour PHP divisée par la taille moyenne d'un processus enfant, multipliée par un Facteur de sécurité Je détermine la RAM par processus avec ps et la colonne RSS ; pour les piles WordPress typiques, 50-250 Mo sont souvent corrects. Sur un serveur de 4 Go, je réserve de la mémoire pour Linux, la base de données et les services de cache, de sorte qu'environ 1,5 à 2 Go sont consacrés à la gestion de la mémoire. PHP resteront à l'écran. Par exemple, si la moyenne du processus est de 100 Mo, 2.000 / 100 × 0,75 = 15 Children. Ce chiffre sert de point de départ, que j'affine en fonction du profil de charge, de la mise en cache et du mélange de plug-ins.

Valeurs de départ pour les configurations typiques de WordPress

Pour les petits blogs avec 2 Go de RAM, 8 enfants, pm = dynamic et un pm.max_requests d'environ 800. Pour les projets moyens avec 4 Go de RAM, je définis 12 enfants, start_servers 4, min_spare_servers 4. Les grandes boutiques à partir de 8 Go de RAM bénéficient de 21 à 40 enfants ; en cas de charge élevée permanente, pm = static peut assurer un débit constant. Je vérifie ensuite le rapport entre l'utilisation du CPU, l'utilisation de la RAM et les temps de réponse afin de procéder à un ajustement fin. Pour ceux qui souhaitent aller plus loin, vous trouverez des informations de fond sous Paramètres PHP-FPM optimaux.

Mesurer les processus : comment déterminer les besoins en RAM

Je détermine d'abord la taille réelle des processus avant de fixer des valeurs, car les boules de cristal ne sont d'aucune aide et coûtent cher. Performance. La commande ps -ylC php-fpm -sort:rss fournit les tailles RSS que j'observe sur quelques minutes. Lors des mises à jour ou des cronjobs, les processus prennent souvent de l'ampleur, c'est pourquoi je tiens compte des pics dans le calcul. En outre, je vérifie les réserves de RAM et la part de swap avec htop et free -h. Avec ces données, je détermine une moyenne robuste et je choisis le facteur de sécurité de manière conservatrice.

Aperçu des paramètres importants

En plus de pm.max_children, d'autres options de pool déterminent la propreté avec laquelle WordPress traite les requêtes et sa capacité à libérer de la mémoire, ce qui peut avoir un impact sensible sur l'efficacité du système. Stabilité pm règle le mode : dynamic adapte le nombre de processus à la charge, static maintient un nombre fixe. pm.max_requests empêche le memory-bloat en redémarrant les processus après X requêtes. request_terminate_timeout protège contre les accrochages dus à des scripts défectueux ou lents. Avec cet ensemble, je couvre 90% des cas pratiques réels.

Paramètres Fonction Recommandation WordPress
pm Mode de contrôle des processus dynamic pour une charge variable ; static pour un trafic élevé permanent
pm.max_children Nombre maximal de travailleurs simultanés RAM PHP disponible / taille du processus × 0,75
pm.max_requests Recyclage des processus 300-1.000 ; plutôt plus bas pour WooCommerce
request_terminate_timeout Abandon des requêtes de longue durée 60-120 secondes contre les accrocs

Dynamic, ondemand ou static - quel mode convient ?

Je choisis le mode adapté au profil de charge : dynamique est ma valeur par défaut, car elle permet d'adapter de manière flexible le nombre de processus actifs et d'économiser ainsi de la RAM lorsque l'activité est faible. static Je l'utilise lorsque la charge est constante et que j'ai besoin de garanties solides en matière de latence et de débit, par exemple pendant les campagnes ou les ventes. ondemand convient aux serveurs ayant de longues périodes d'inactivité : Les processus ne sont créés qu'en cas de besoin et sont arrêtés après une période d'inactivité. Le trade-off, ce sont les démarrages à froid ; la première demande par nouveau processus semble plus lente. Pour ondemand, je mets pm.process_idle_timeout (par ex. 10-20s), pour les dynamiques, je garde start_servers, min_spare_servers et max_spare_servers étroite, afin que le pool évolue rapidement, mais ne „gonfle“ pas.

Exemple de configuration pour ta piscine

Sur Debian/Ubuntu, le fichier de pool se trouve généralement dans /etc/php/8.x/fpm/pool.d/www.conf, ce qui me donne une idée claire de ce qu'est un pool. Structure pour les adaptations. Je règle pm sur dynamic, je fixe une valeur réaliste pour pm.max_children et je garde les serveurs de secours étroits. Je règle le recyclage sur 500 pour éviter les fuites et les montées de RAM. Après chaque modification, je teste la charge et élimine les goulets d'étranglement avant d'augmenter les valeurs. Pour en savoir plus sur les valeurs limites, consultez le site Optimiser pm.max_children.

pm = dynamic
pm.max_children = 15
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500
request_terminate_timeout = 90s

Plusieurs pools, sockets et isolation propre

Dans le cas de plusieurs projets ou de rôles clairement séparés (frontend vs. admin/REST), je mets en place piscines séparées avec son propre utilisateur et son propre socket. Ainsi, chaque pool limite lui-même ses children et un fuyard ne bloque pas le reste. Sur un hôte, je préfère Sockets Unix par rapport à TCP (listen = /run/php/site.sock) - moins de latence, moins d'overhead. J'utilise TCP entre Nginx/Apache et PHP-FPM sur différents hôtes/conteneurs. Je mets listen.owner, listen.group et listen.mode et, si nécessaire, j'ai levé listen.backlog afin d'éviter que les courts pics de charge ne se transforment en erreurs de connexion. Avec un pool d'administrateurs dédié, je peux créer un pool plus étroit. request_terminate_timeout conduire et pm.max_requests sans pour autant freiner le pool de front-end à forte mise en cache.

Reconnaître les symptômes et réagir correctement

Si le journal d'erreurs indique régulièrement „server reached pm.max_children“, le pool limite les Parallélisme et j'augmente modérément. Si 502/504 apparaissent alors que l'utilisation du swap est élevée, je réinitialise pm.max_children et j'abaisse pm.max_requests. Si le CPU augmente alors que l'utilisation de la RAM est faible, ce sont généralement les requêtes ou la logique PHP qui bloquent ; j'optimise la base de données et la mise en cache. Si les requêtes restent bloquées, un request_terminate_timeout plus strict et une analyse des logs avec des timestamps aident. Je vérifie les pics remarquables par rapport aux tâches cron, aux index de recherche et aux actions d'administration.

Statut du FPM et Slowlog : un diagnostic précis

J'active le Statut par pool (pm.status_path) et lire des indicateurs tels que processus actifs, max children reached, listen queue et max listen queue est désactivée. Une file d'attente de listes qui s'agrandit en permanence montre clairement qu'il y a trop peu d'enfants ou que les backends bloquent. En outre, je place request_slowlog_timeout (par ex. 3-5s) et un slowlog-chemin d'accès. Je vois ainsi des traces de pile de requêtes qui traînent - il s'agit souvent d'appels HTTP externes, de requêtes WooCommerce complexes ou de manipulations d'images. Avec catch_workers_output les avertissements des travailleurs sont rassemblés dans les logs. Sur la base de ces données, je décide si davantage de parallélisme est utile ou si je dois résoudre des goulots d'étranglement dans le code/la base de données.

Monitoring : 3-5 jours d'évaluation propre

Après le réglage, j'observe les pics de charge pendant plusieurs jours, car les pics de charge à court terme peuvent être très importants. fluctuations se tromper. J'enregistre la RAM, le swap, 502/504, TTFB et le nombre de processus actifs dans l'état FPM. En dessous de 80 % d'utilisation de la RAM sans swap et sans files d'attente, je suis dans le vrai. Si des goulots d'étranglement apparaissent lors d'actions telles que le checkout, la recherche ou les importations, je modifie de manière ciblée pm.max_children et pm.max_requests. Chaque étape fait l'objet de petits ajustements et d'une nouvelle mesure.

La facture mémoire en détail : RSS, PSS et mémoire partagée

La taille du processus est perfide : RSS (Resident Set Size) contient également des segments partagés comme OPcache et les bibliothèques. C'est pourquoi je surestime rapidement la consommation de RAM si je calcule simplement „RSS × Children“. Il vaut mieux utiliser la PSS-(Proportional Set Size), qui répartit la mémoire partagée de manière équitable entre les processus - des outils comme smem aident ici. Le calcul comprend OPcache (par exemple 256 Mo + strings), APCu (par ex. 64-128 Mo) et le processus maître. Le PHP memory_limit n'est pas une moyenne, mais la limite supérieure par requête ; des pics isolés peuvent survenir, mais c'est la moyenne qui compte. Je prévois une mémoire tampon pour que les pics, les déploiements et les cronjobs ne déclenchent pas immédiatement de swap et je laisse pm.max_requests agir consciemment pour limiter le blocage de la mémoire.

Réduire la charge spécifique à WordPress

Je réduis d'abord la charge PHP avant d'augmenter encore Children, car un taux de réussite de cache plus rapide permet d'économiser des ressources réelles. RAM. Les caches pleine page réduisent drastiquement les requêtes PHP, ce qui libère de la capacité pour le checkout, la recherche et l'admin. OPcache avec memory_consumption autour de 256 Mo accélère le bytecode et décharge le pool. Je maintiens la memory_limit PHP à 256M, afin que les plugins ne ralentissent pas le serveur. Pour plus d'informations sur les goulots d'étranglement, voir le guide PHP Worker comme goulot d'étranglement.

Équilibre entre les backends de la base de données et du cache

Chaque travailleur PHP génère potentiellement une Connexion à la base de données. Si j'augmente pm.max_children, la charge simultanée de la base de données augmente également. Je vérifie donc MySQL/MariaDB : max_connections, tampon (innodb_buffer_pool_size), et le planificateur de requêtes. Redis/Memcached doivent suivre en parallèle - maxclients, garder un œil sur la limite de mémoire et les latences. Une instance WordPress avec 20 enfants actifs peut facilement saturer la base de données si plusieurs requêtes coûteuses sont exécutées en parallèle. C'est pourquoi je tune la BD (index, requêtes lentes) et je mise sur caches d'objets persistants, avant de libérer d'autres children. Cela me permet d'augmenter le débit sans écraser le backend.

WooCommerce, Cron et Admin : cas particuliers

Les boutiques génèrent davantage de requêtes dynamiques simultanées, c'est pourquoi j'ai utilisé quelque chose pour les checkouts. air à pm.max_children. En même temps, j'abaisse plutôt pm.max_requests afin de couper la mémoire bloquée en permanence. Pour les importations et les tâches cron, je prévois un budget supplémentaire ou j'exécute les tâches en dehors des heures de pointe. La zone d'administration est souvent en pointe à court terme ; la mise en cache protège moins ici, donc un contrôle efficace du pool est important. En cas de signes de files d'attente, j'augmente par petites étapes et j'observe les métriques immédiatement après.

Conteneurs, quotas vCPU et pièges OOM

Dans les conteneurs et les VM, l'attention se porte sur le efficace limite de RAM (cgroups), pas à l'hôte. Je calcule donc pm.max_children à partir de la limite allouée et non de „free -h“. Les OOM de conteneurs sont impitoyables - le noyau met fin aux processus de manière brutale. Les quotas CPU comptent également : Plus de children ne servent à rien si 1 ou 2 vCPUs limitent le temps de calcul. En règle générale, pour les charges de travail WordPress à forte composante IO, je m'adapte à environ 2-4× le nombre de vCPU ; au-delà, les changements de contexte augmentent, mais pas le débit réel. Dans les environnements orchestrés, je déploie les modifications de manière conservatrice, j'observe les redémarrages de pods et je maintiens les tests de lecture/viabilité de manière à ce que les courtes phases d'échauffement de FPM ne soient pas considérées comme des pannes.

Des sources d'erreurs souvent négligées

De nombreux problèmes ne proviennent pas de la piscine, mais de Plugins, qui multiplient les requêtes ou génèrent de longs processus. Les recherches indexées, les règles de crawler cassées et les intervalles de heartbeat surréalistes font grimper la charge. C'est pourquoi je vérifie toujours en premier lieu les logs, le Query Monitor et les en-têtes de cache. Si la charge n'apparaît que sur certaines URL, j'interprète cela comme une indication de goulots d'étranglement de plugins ou de modèles. Ce n'est que lorsque ces problèmes ont été résolus que je continue à faire évoluer Children.

Comprendre les sessions, Admin-AJAX et les verrous

WordPress/plugins fonctionne en partie avec Sessions. Les verrous de session basés sur des fichiers peuvent rendre les requêtes sérielles - une seule requête lente bloque le reste du même identifiant de session. Je limite l'utilisation des sessions et vérifie que les rafales AJAX d'admin (wp-admin/admin-ajax.php) ne sont pas inutilement activées. Le heartbeat doit être limité de manière raisonnable, sinon il génère une charge sans valeur ajoutée. Si des blocages ou de longs accès aux fichiers se produisent, un parallélisme accru n'apporte pas de solution ; la mise en cache, des E/S de stockage plus rapides ou un autre gestionnaire de session peuvent aider. Dans les logs, je reconnais de tels modèles à de nombreuses requêtes similaires démarrant simultanément et présentant des durées d'exécution inhabituellement longues.

Vue d'ensemble des délais Nginx, Apache et FastCGI

Le serveur web impose lui aussi des limites que je dois harmoniser avec les valeurs FPM, sans quoi Tuning. Sous Nginx, je fais attention à fastcgi_read_timeout et à un nombre suffisant de processus de travail. Sous Apache, je vérifie mpm_event, les paramètres de Keepalive et les délais d'attente du proxy. Si ces limites ne sont pas correctes, les utilisateurs signalent des délais d'attente alors que FPM a encore de la capacité. Des budgets temporels uniformes permettent de maintenir la cohérence du chemin entre le client et PHP.

Stratégie de déploiement, tests et opérations

Je déploie progressivement les modifications de pm.max_children et les teste sous charge réelle. Un rechargement de FPM (graceful) reprend les configurations sans interruption de la connexion. Avant les sauts importants, je simule des pics (par exemple le démarrage de la vente) et j'observe alors listen queue, CPU, RAM, 95e-99e percentile de latence et taux d'erreur. Je documente les hypothèses retenues afin que les membres ultérieurs de l'équipe comprennent pourquoi une valeur a été choisie de cette manière. Je définis des alarmes : swap > 0, „max children reached“ dans le statut, augmentation de 502/504, et latence de la BD. Ainsi, la plateforme reste stable même des mois plus tard, lorsque le trafic et le mix de plugins changent.

En bref

Mauvaise mise en place PHP-FPM-Les enfants ralentissent WordPress, soit dans les files d'attente, soit dans la limite de la RAM. Je détermine la taille du processus, je réserve de la mémoire pour les services système et je définis pm.max_children avec une mémoire tampon. Ensuite, je contrôle pm.max_requests, request_terminate_timeout et le mode pm = dynamic ou static selon l'image de charge. La mise en cache, OPcache et des plugins propres réduisent sensiblement le nombre de requêtes PHP. En appliquant ces mesures de manière conséquente, les pages restent réactives et le serveur fiable.

Derniers articles