...

Charge CPU inégale dans WordPress – comment les tâches cron peuvent nuire aux performances

Une charge CPU inégale dans WordPress est souvent due à une mauvaise configuration. wordpress cronjobs, qui démarrent en arrière-plan à chaque consultation de page et provoquent ainsi des pics. Je vais vous montrer comment ces déclencheurs allongent le TTFB, mobilisent les workers PHP et génèrent des latences, et comment vous pouvez revenir à plus uniforme Tu arrives.

Points centraux

L'aperçu suivant résume les aspects les plus importants avant que je n'entre dans les détails et n'explique les étapes concrètes. Je vais garder cette liste courte afin de me concentrer sur Action et l'effet.

  • WP-Cron se déclenche lors des consultations de pages et génère une charge imprévisible.
  • Processus PHP s'accumulent lors du trafic et ralentissent le TTFB.
  • Cron système Dissocier les tâches du flux de visiteurs.
  • Intervalles et les priorités lissent les pics d'utilisation du processeur.
  • Suivi détecte les goulots d'étranglement et les événements erronés.

Ce que font réellement les tâches cron WordPress – et d'où vient la charge

WordPress utilise un système pseudo-cron : lors de l'appel, wp-cron.php est déclenché par POST, vérifie les événements à venir et lance des tâches telles que les publications, les vérifications de mises à jour, l'enregistrement des brouillons via Heartbeat et le nettoyage de la base de données – chaque événement coûte temps CPU. Cette approche semble pratique, mais elle génère des déclencheurs incontrôlables, car ce sont les visites qui déterminent l'exécution et non un minuteur planifiable. Lorsque plusieurs appels se produisent simultanément, des processus PHP parallèles démarrent et se disputent les travailleurs. Les configurations multisites renforcent cet effet, car chaque sous-site gère sa propre pile d'événements, augmentant ainsi le nombre de vérifications [1]. Si vous souhaitez approfondir ces relations, vous trouverez des informations de base détaillées à l'adresse suivante Comprendre WP-Cron, mais le message principal reste le même : le guidage des visiteurs ne constitue pas un moyen fiable horloge.

Le véritable frein : les processus PHP parallèles via wp-cron.php

Chaque déclencheur Cron lance un processus PHP distinct qui lie un worker et utilise ainsi la mémoire disponible. temps de calcul pour les rendus de pages réels. Si les déclencheurs s'accumulent, le temps d'attente pour un travailleur libre augmente, le TTFB s'allonge et le premier octet arrive plus tard dans le navigateur [2]. Les mesures ont montré un retard pouvant atteindre 800 millisecondes, ce qui affecte les Core Web Vitals et réduit la visibilité organique [3]. L'hébergement mutualisé ou les paramètres PHP-FPM trop restrictifs aggravent cet effet, car max_children est rapidement atteint et les processus se retrouvent dans des files d'attente. Cela peut devenir un cercle vicieux, en particulier pendant les pics d'activité des boutiques ou les campagnes : plus de trafic génère plus de vérifications Cron, qui à leur tour bloquent le rendu et ainsi Temps de chargement étirer [1][2].

Gérer correctement la mise en cache, le CDN et les pièges de bouclage

WP-Cron utilise par défaut un demande de bouclage sur votre propre domaine. S'il y a un cache de page agressif, un CDN ou un blocage Basic Auth, l'appel peut échouer ou attendre – les exécutions Cron s'arrêtent, se répètent et prolongent ainsi la liaison CPU. Je m'assure donc que /wp-cron.php n'est pas mis en cache, n'est pas limité en débit et est accessible en interne. Le cron système atténue cette vulnérabilité car il sans HTTP-Loopback exécute directement PHP. Si un proxy est en amont, je vérifie en outre si les requêtes adressées à 127.0.0.1 être transmis correctement et qu'aucune règle WAF ne bloque le point final. Pendant les phases de maintenance, il est important soit de suspendre délibérément Cron, soit de laisser passer explicitement le point final afin que les tâches en attente ne soient pas „ relancées “ sous forme de paquet.

Détecter et classer les charges CPU irrégulières

Les pics de charge aux heures de pointe sont typiques. Ils ne s'expliquent pas uniquement par le nombre de visiteurs, mais aussi par des vagues Cron provenant d'événements en retard qui s'accumulent et se déclenchent simultanément. Les installations multisites multiplient la charge, car chaque sous-site gère des listes Cron et est vérifié lors de la visite. Il en résulte des pics courts mais importants, que les fichiers journaux affichent sous forme de cascades de wp-cron.php-POSTs [1]. Souvent, les plugins enregistrent leurs propres événements à des intervalles trop courts, parfois toutes les cinq minutes ou plus, ce qui, avec dix plugins, se traduit rapidement par des dizaines de vérifications à chaque appel. Faites également attention à votre Limite du nombre de workers PHP, car des Worker saturés entraînent des temps d'attente que les utilisateurs ressentent directement. En lisant ces modèles, on comprend que la courbe irrégulière est le résultat de déclencheurs et non une inévitabilité. humeur du trafic.

Pourquoi System Cron lisse la charge

Un véritable cron système dissocie les tâches du flux de visiteurs et définit une cadence claire, par exemple toutes les cinq minutes, toutes les heures ou tous les jours, ce qui permet de planifier l'exécution et de répartir la charge de manière uniforme [1][6]. Les visiteurs ne déclenchent alors plus de tâches cron, ce qui soulage le TTFB et donne la priorité au rendu. Même en cas de faible trafic, les tâches s'exécutent de manière fiable, car le serveur les exécute même si personne ne visite le site. Cela permet aux mises à jour, aux e-mails ou aux pings d'index de s'exécuter à temps et empêche les événements de „ rester en suspens “ et de se déclencher plus tard sous forme de paquet. Je crée ainsi une prévisibilité. charge du système, qui ne varie pas en fonction des caprices du trafic.

Étape par étape : désactiver WP-Cron et configurer System-Cron

Je commence par désactiver le déclencheur interne dans le fichier wp-config.php afin qu'aucun appel de page ne lance plus de tâches cron. Pour ce faire, ajoutez la ligne suivante et enregistrez le fichier afin que WordPress ne déclenche pas de vérification cron lors du rendu. Ensuite, je configure une règle crontab propre qui déclenche wp-cron.php de manière cyclique sans générer de sortie inutile. Ainsi, la tâche s'exécute de manière programmée et allège considérablement les chargements de pages. Résultat : le rendu est prioritaire, les tâches cron ont leur propre cadence.

// wp-config.php define('DISABLE_WP_CRON', true);
# Exemple de crontab (toutes les 5 minutes) */5 * * * * php -q /var/www/html/wp-cron.php > /dev/null 2>&1

WP-CLI au lieu d'un appel PHP direct

Pour un meilleur contrôle, je préfère définir l'exécution cron via WP-CLI . Cela me permet d'exécuter „ uniquement les événements échus “, de les enregistrer de manière plus détaillée et de traiter les multisites de manière ciblée. De plus, un verrou empêche le démarrage simultané de plusieurs exécutions.

# WP-CLI : traiter uniquement les événements échus */5 * * * * /usr/local/bin/wp cron event run --due-now --path=/var/www/html --quiet

# Avec un verrou simple via flock (recommandé) */5 * * * * flock -n /tmp/wp-cron.lock /usr/local/bin/wp cron event run --due-now --path=/var/www/html --quiet

Dans les environnements multisites, je peux ainsi, via --url= Parcourir le site page par page ou faire défiler les sites à l'aide d'une petite boucle shell. Cela évite que 100 sous-sites soient consultés simultanément au même moment et génèrent des pics de charge.

Intervalles et priorités : quelles tâches doivent être exécutées et à quel moment ?

Toutes les tâches ne nécessitent pas une exécution toutes les minutes ; je les classe par ordre d'importance et de coût afin que les tâches critiques pour le référencement soient prioritaires et que les tâches coûteuses soient reportées aux heures creuses [1]. L'accent est mis sur la création de plans de site, les pings d'indexation et le cache warming, suivis par la maintenance de la base de données et la suppression des données transitoires. Je planifie les sauvegardes pendant les plages horaires nocturnes et choisis des procédures incrémentielles afin d'éviter les pics d'E/S. Je regroupe les files d'attente des newsletters ou les importateurs et les laisse fonctionner dans des créneaux fixes au lieu de les vérifier à chaque consultation de la page. Cet ordre permet de définir des priorités claires et empêche que des intervalles de sondage courts ne CPU boucher.

Tâche Intervalle recommandé Impact sur le processeur Remarque
Plan du site/indexation des pings toutes les heures jusqu'à 1 fois par jour faible Pertinent pour le référencement ; avant le cache warming donner la priorité
Préchauffage du cache 1 à 2 fois par jour moyen Échelonner les URL, pas d'analyse complète aux heures de pointe
Sauvegardes la nuit élevé Incrémental ; destination distante avec limite de bande passante
Nettoyage de la base de données quotidiennement ou hebdomadairement moyen Révisions/transitoires en blocs supprimer
Notifications par e-mail toutes les heures/1 fois par jour faible Créer des lots, utiliser la file d'attente

Mécanismes à exécution unique et verrous propres

Pour éviter que les tâches Cron ne se chevauchent, je définis en plus flock également les restrictions propres à WordPress. WP_CRON_LOCK_TIMEOUT définit la durée pendant laquelle une exécution reste exclusive. Si la page est lente ou si les tâches sont longues, j'augmente légèrement la valeur afin qu'aucun deuxième processus ne démarre prématurément. À l'inverse, je la diminue lorsque les tâches sont courtes et qu'un blocage ne doit pas déclencher de cascade.

// wp-config.php – Durée de verrouillage en secondes (valeur par défaut : 60) define('WP_CRON_LOCK_TIMEOUT', 120);

De plus, je limite délibérément le parallélisme dans les plugins (tailles des lots, longueurs de pas, temps d'attente entre les requêtes). Cela m'évite qu'une exécution cron génère à son tour des dizaines de processus PHP et fasse grimper la courbe de charge.

Surveillance et analyse : mettre en évidence les goulots d'étranglement

Je commence par les journaux d'accès et filtre les requêtes POST sur wp-cron.php afin d'identifier la fréquence et les plages horaires ; de nombreux intervalles courts indiquent des intervalles rapprochés ou des événements bloquants. En parallèle, je vérifie les journaux d'erreurs pour détecter les délais d'attente, les verrouillages et les temps d'attente de la base de données qui affectent les tâches cron. Dans le backend, WP Crontrol donne un aperçu des événements enregistrés, de leurs hooks et de leurs durées d'exécution prévues ; j'y supprime les entrées obsolètes ou en attente. Pour obtenir des informations plus détaillées sur les transactions, les temps de requête et les files d'attente PHP-FPM, j'utilise Outils APM pour WordPress pour isoler les points sensibles. Cela me permet d'identifier les causes plutôt que de simplement atténuer les symptômes, et d'agir de manière ciblée. Mesures donner la priorité à.

Objectifs mesurables et test rapide en 10 minutes

Je définis des valeurs cibles claires : TTFB p95 pour les pages mises en cache inférieures à 200-300 ms, pour les pages non mises en cache inférieures à 800 ms ; file d'attente PHP-FPM durablement proche de 0 ; CPU sans pics extrêmes menant à la saturation. Le test rapide : désactiver WP-Cron, définir System-Cron, traiter les événements échus une seule fois via WP-CLI, puis vérifier les journaux. En 10 minutes, vous verrez si le TTFB diminue, si la file d'attente PHP se réduit et si des hooks particuliers (par exemple, les vérifications de mise à jour, les importateurs) en sont la cause principale. Ensuite, ajustez les intervalles, la taille des lots et la cadence jusqu'à ce que les courbes soient stables.

Maîtriser l'API Heartbeat et les événements du plugin

Le mécanisme Heartbeat actualise les sessions et les brouillons, mais génère souvent des requêtes inutiles dans le frontend ; je le limite aux zones d'administration ou je définis des intervalles appropriés. De nombreux plugins enregistrent des tâches cron avec des valeurs par défaut trop rapprochées ; je passe ici à des intervalles plus longs et déplace les tâches vers des heures creuses. Dans les configurations de boutique, je limite les flux d'inventaire et les synchronisations de prix à des créneaux fixes, au lieu de les polliner toutes les minutes. Pour les flux et le cache warming, j'utilise des listes par lots afin que toutes les URL ne soient pas exécutées en une seule fois. Ces interventions réduisent la fréquence des requêtes et lissent le courbe clairement.

Mise à l'échelle : des tâches cron aux files d'attente et aux travailleurs

En cas de trafic élevé, je réduis autant que possible WP-Cron et transfère les tâches gourmandes en ressources informatiques dans des files d'attente avec des workers dédiés. Les files d'attente de tâches répartissent la charge sur plusieurs processus, peuvent être étendues horizontalement et évitent au frontend d'avoir à attendre. Dans les configurations de conteneurs ou d'orchestration, je fais évoluer les workers indépendamment de PHP-FPM, ce qui permet au rendu et au travail en arrière-plan de bénéficier de ressources distinctes. Les files d'attente sont particulièrement utiles pour les importations, le traitement d'images, les lots de newsletters et les synchronisations API. Ainsi, le frontend reste réactif, tandis que les tâches en arrière-plan sont contrôlées et planifiable courir.

WooCommerce, Action Scheduler et longues files d'attente

WooCommerce apporte avec le Planificateur d'actions une file d'attente dédiée qui traite les e-mails de commande, les webhooks, les abonnements et les synchronisations. C'est précisément là que des pics d'utilisation du processeur peuvent survenir lorsque des milliers d'actions sont „ en attente “. Je ne laisse pas le runner s'exécuter lors de l'appel de la page, mais je le déclenche via System Cron ou WP-CLI dans des fenêtres fixes. Je règle la taille des lots et le parallélisme de manière à ce qu'une exécution ne bloque pas la base de données et que les workers PHP-FPM restent libres. Je répartis les importateurs, la régénération d'images et les pics de webhooks en plusieurs petits passages – mieux vaut 10 fois brièvement qu'une fois pendant des heures avec des blocages d'E/S.

Spécificités multisites : équilibrer la synchronisation par site

Dans les configurations multisites, la charge s'accumule car chaque site dispose de sa propre liste d'événements. Au lieu de tout vérifier toutes les cinq minutes, je fais tourner les sites : des groupes de sites avec des cadences légèrement décalées afin que toutes les listes cron ne s'exécutent pas en même temps. Pour les sites très actifs, la file d'attente obtient plus souvent un slot, les sites calmes moins souvent. Il en résulte une courbe CPU plus régulière et moins de concurrence entre les travailleurs, pour un travail total identique.

Test pratique : configuration sans pièges

Je vérifie d'abord si DISABLE_WP_CRON est correctement défini, car les déclencheurs doubles (internes + externes) aggravent les pics de charge. Ensuite, je vérifie le crontab : chemin d'accès correct, pas de sortie inutile, intervalle raisonnable et pas de chevauchement avec les fenêtres de sauvegarde. Dans WP Crontrol, je nettoie les hooks obsolètes et je remplace les intervalles courts par des cycles réalistes. J'adapte les paramètres PHP-FPM au profil des visiteurs afin que les PHP-Workers ne soient pas constamment à la limite supérieure. Enfin, je trace le TTFB, les temps de réponse et le CPU afin d'évaluer clairement l'effet des modifications. évaluer.

Dimensionner correctement PHP-FPM, OPCache et les limites de temps

La meilleure stratégie Cron échoue si PHP-FPM est trop petit ou mal synchronisé. Je choisis pm=dynamic ou pm=à la demande en fonction du profil de trafic et transférer pm.max_children à partir du budget RAM réel : en règle générale, RAM_pour_PHP / consommation moyenne du script. Exemple : un budget de 2 Go et ~128 Mo par processus donnent ~16 workers. pm.max_requests Je le règle modérément (500-1000) afin de limiter les fuites. request_terminate_timeout limite les tâches exceptionnelles ; un nettoyage slowlog détecte les boucles de requêtes et les temps d'attente externes. Un OPCache sain (suffisamment max_accelerated_files, memory_consumption, interned_strings_buffer) empêche les démarrages à froid et économise des ressources CPU par requête, y compris pour les tâches cron.

Cache d'objets et hygiène des options

Un cache objet persistant (par exemple Redis/Memcached) réduit considérablement la pression sur la base de données pour les vérifications Cron. Il est important de hygiène dans la wp_optionsTableau : l'option cron ne doit pas dépasser plusieurs mégaoctets, sinon chaque vérification devient coûteuse. Je supprime les événements obsolètes ou bloqués, je réduis les fichiers autoload inutiles et je désactive les options volumineuses et rarement utilisées. autoload = non. Cela réduit les temps de requête et permet d'évaluer plus rapidement les listes Cron.

Réglage fin : rythme, ordre et limites des ressources

Pour les sites web qui connaissent des pics d'activité le matin, je programme le cache warming tôt dans la nuit et lance les sitemaps juste avant les heures d'ouverture afin que les crawlers voient les données actualisées. Je divise les nettoyages de bases de données coûteux en blocs plus petits afin de réduire les temps de verrouillage et d'éviter les pics de requêtes. Je programme les exportations volumineuses pendant les fenêtres du week-end, où il y a moins d'interactions. Lorsque cela est judicieux, je limite les tâches parallèles afin que plusieurs processus cron-php ne se disputent pas simultanément les E/S. Ce réglage fin garantit un débit régulier et une meilleure Temps de réponse.

Sécurité : protéger wp-cron.php contre les accès externes

Comme Cron doit être déclenché en interne, je bloque l'accès externe direct à /wp-cron.php. Vous éviterez ainsi les abus, les attaques DDoS et les appels externes accidentels. N'autorisez que les appels locaux (loopback ou CLI) et bloquez tout le reste. Cela réduit le bruit dans les journaux et protège les workers PHP.

# Exemple Nginx location = /wp-cron.php { allow 127.0.0.1; deny all; include fastcgi_params; fastcgi_pass php-fpm; }

# Exemple Apache  Require ip 127.0.0.1

Causes fréquentes de la charge „ fantôme “ due à Cron

Les intervalles très courts (1 à 5 minutes) pour les tâches non critiques sont parmi les principaux facteurs de charge, en particulier lorsqu'ils sont associés à de nombreux plugins. Les événements bloqués, qui sont sans cesse replanifiés en raison d'échecs d'exécution, génèrent des boucles qui inondent les journaux. Les problèmes de verrouillage dans la base de données obligent les tâches cron à s'exécuter plus longtemps, ce qui augmente les chevauchements. De plus, les blocages HTTP (par exemple, DNS ou API à distance) peuvent prolonger artificiellement les exécutions cron et immobiliser les travailleurs. Connaître ces schémas permet de gagner beaucoup de temps dans la recherche des causes et de réduire les Peaks rapide.

En bref

Une charge CPU irrégulière dans WordPress provient souvent de WP-Cron, qui agit comme un déclencheur lors des consultations de pages et lie les PHP-Workers. Je désactive le déclencheur interne, je configure un cron système, j'optimise les intervalles et je donne la priorité aux tâches pertinentes pour le référencement afin que le rendu soit prioritaire. La surveillance à l'aide de journaux, de WP Crontrol et d'analyses APM me permet de détecter les événements erronés, les cycles courts et les processus bloquants. Pour les projets de grande envergure, je déplace les tâches gourmandes en ressources informatiques vers des files d'attente afin de séparer clairement les tâches frontales et les tâches en arrière-plan. Cette approche permet d'obtenir une charge uniforme, un TTFB plus court et une amélioration notable. plus rapide Livraison – sans pics imprévus.

Derniers articles