Geekflare est soutenu par son public. Nous pouvons percevoir des commissions d'affiliation sur les liens d'achat présents sur ce site.
En Développement Dernière mise à jour : 16 septembre 2023
Partager sur :
Invicti Web Application Security Scanner - la seule solution qui offre une vérification automatique des vulnérabilités avec Proof-Based Scanning™.

PHP est omniprésent et c'est sans doute le langage le plus largement déployé sur l'internet.

Cependant, il n'est pas vraiment connu pour ses capacités de haute performance, en particulier lorsqu'il s'agit de systèmes hautement concurrents. C'est la raison pour laquelle des langages tels que Node (oui, je sais, ce n'est pas un langage) sont utilisés pour ces cas d'utilisation spécialisés, Aller et Elixir prennent le relais.

Cela dit, vous pouvez faire BEAUCOUP de choses pour améliorer la qualité de l'information. Performances de PHP sur votre serveur. Cet article se concentre sur les php-fpm ce qui est la façon naturelle de configurer votre serveur si vous utilisez Nginx.

Au cas où vous sauriez ce qu'est un php-fpm n'hésitez pas à passer à la section sur l'optimisation.

Qu'est-ce que PHP-fpm ?

Peu de développeurs s'intéressent à la DevOps Et même parmi ceux qui le font, très peu savent ce qui se passe sous le capot. Il est intéressant de noter que lorsque le navigateur envoie une requête à un serveur utilisant PHP, ce n'est pas PHP qui constitue le premier point de contact, mais le serveur HTTP, dont les principaux sont Apache et Nginx. Ces "serveurs web" doivent ensuite décider comment se connecter à PHP et lui transmettre le type de requête, les données et les en-têtes.

request-response-in-php-e1542398057451
Le cycle demande-réponse dans le cas de PHP (Image credit : ProinerTech)

Dans les applications PHP modernes, la partie "trouver un fichier" ci-dessus est la fonction index.phpà laquelle le serveur est configuré pour déléguer toutes les demandes.

La façon dont le serveur web se connecte à PHP a évolué, et cet article serait trop long si nous devions entrer dans les détails. Mais grosso modo, à l'époque où Apache dominait en tant que serveur web de choix, PHP était un module inclus dans le serveur.

Ainsi, à chaque fois qu'une requête était reçue, le serveur démarrait un nouveau processus, qui incluait automatiquement PHP et l'exécutait. Cette méthode s'appelle mod_phpabréviation de "PHP as a module" (PHP en tant que module). Cette approche avait ses limites, que Nginx a surmontées grâce à la technologie php-fpm.

En php-fpm la responsabilité de la gestion de PHP incombe au programme PHP au sein du serveur. En d'autres termes, le serveur web (Nginx, dans notre cas), ne se soucie pas de savoir où se trouve PHP et comment il est chargé, tant qu'il sait comment envoyer et recevoir des données. Si vous voulez, vous pouvez considérer PHP dans ce cas comme un autre serveur en lui-même, qui gère quelques processus PHP enfants pour les requêtes entrantes (ainsi, nous avons la requête qui atteint un serveur, qui est reçue par un serveur et transmise à un autre serveur - assez fou ! :-P).

Si vous avez déjà configuré Nginx, ou même si vous l'avez déjà fait, vous rencontrerez quelque chose comme ceci :

     location ~ .php$ {
        try_files $uri =404 ;
        fastcgi_split_path_info ^(.+.php)(/.+)$ ;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock ;
        fastcgi_index index.php ;
        include fastcgi_params ;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name ;
    }

La ligne qui nous intéresse est la suivante : fastcgi_pass unix:/run/php/php7.2-fpm.sock;qui indique à Nginx de communiquer avec le processus PHP à travers la socket nommée php7.2-fpm.sock. Ainsi, pour chaque requête entrante, Nginx écrit des données dans ce fichier et, lorsqu'il reçoit la sortie, la renvoie au navigateur.

Une fois de plus, je dois souligner qu'il ne s'agit pas de l'image la plus complète ou la plus précise de ce qui se passe, mais qu'elle est tout à fait exacte pour la plupart des tâches DevOps.

Ceci mis à part, récapitulons ce que nous avons appris jusqu'à présent :

  • PHP ne reçoit pas directement les requêtes envoyées par les navigateurs. Les serveurs web comme Nginx les interceptent d'abord.
  • Le serveur web sait comment se connecter au processus PHP et transmet toutes les données de la requête (il colle littéralement tout) à PHP.
  • Lorsque PHP a terminé son travail, il renvoie la réponse au serveur web, qui la renvoie au client (ou au navigateur, dans la plupart des cas).

Ou graphiquement :

php-et-nginx
Comment PHP et Nginx fonctionnent ensemble (Image credit : DataDog)

C'est bien jusqu'à présent, mais maintenant vient la question à un million de dollars : qu'est-ce que PHP-FPM exactement ?

La partie "FPM" de PHP signifie "Fast Process Manager" (gestionnaire de processus rapide), ce qui est une façon élégante de dire que le PHP qui tourne sur un serveur n'est pas un processus unique, mais plutôt des processus PHP qui sont créés, contrôlés et supprimés par ce gestionnaire de processus FPM. C'est à ce gestionnaire de processus que le serveur web transmet les requêtes.

Le PHP-FPM est un trou de lapin à part entière, alors n'hésitez pas à l'explorer si vous le souhaitez, mais pour ce qui nous concerne, cette explication suffira 🙂 .

Pourquoi optimiser PHP-fpm ?

Alors pourquoi se préoccuper de toute cette danse quand tout va bien ? Pourquoi ne pas laisser les choses en l'état ?

Paradoxalement, c'est précisément le conseil que je donne pour la plupart des cas d'utilisation. Si votre installation fonctionne bien et n'a pas de cas d'utilisation extraordinaires, utilisez les valeurs par défaut. Cependant, si vous envisagez de passer à une échelle supérieure à celle d'une seule machine, il est essentiel de tirer le maximum d'une seule machine, car cela peut réduire de moitié (voire plus !) la facture du serveur.

Une autre chose à réaliser est que Nginx a été conçu pour gérer d'énormes charges de travail. Il est capable de gérer des milliers de connexions en même temps, mais si ce n'est pas le cas de votre installation PHP, vous ne ferez que gaspiller des ressources car Nginx devra attendre que PHP termine le processus en cours et accepte le suivant, ce qui aura pour effet de réduire à néant tous les avantages que Nginx a été conçu pour offrir !

Ceci étant dit, examinons ce que nous changerions exactement pour optimiser le système. php-fpm.

Comment optimiser PHP-FPM ?

L'emplacement du fichier de configuration pour php-fpm peut varier d'un serveur à l'autre, vous devrez donc faire quelques recherches pour le trouver. Vous pouvez utiliser commande de recherche sous UNIX. Sur mon Ubuntu, le chemin est /etc/php/7.2/fpm/php-fpm.conf. La version 7.2 est, bien sûr, la version de PHP que j'utilise.

Voici à quoi ressemblent les premières lignes de ce fichier :

 ;;;;;;;;;;;;;;;;;;;; ;
Configuration FPM ;
;;;;;;;;;;;;;;;;;;;; ;

Tous les chemins relatifs dans ce fichier de configuration sont relatifs au préfixe d'installation de PHP (/usr).
; préfixe (/usr). Ce préfixe peut être modifié dynamiquement en utilisant l'argument
; '-p' en ligne de commande.

;;;;;;;;;;;;;;;;; ;
Options globales ;
;;;;;;;;;;;;;;;;; ;

[global]
; Fichier Pid
; Note : le préfixe par défaut est /var
; Valeur par défaut : none
pid = /run/php/php7.2-fpm.pid

; Fichier journal des erreurs
; S'il est défini sur "syslog", le journal est envoyé à syslogd au lieu d'être écrit
dans un fichier local.
Remarque : le préfixe par défaut est /var.
; Valeur par défaut : log/php-fpm.log
error_log = /var/log/php7.2-fpm.log

Quelques éléments devraient être immédiatement évidents : la ligne pid = /run/php/php7.2-fpm.pid nous indique quel fichier contient l'identifiant de processus de l'application php-fpm processus.

Nous constatons également que /var/log/php7.2-fpm.log est l'endroit où php-fpm va stocker ses journaux.

A l'intérieur de ce fichier, ajoutez trois autres variables comme ceci :

Seuil de redémarrage d'urgence 10
Intervalle de redémarrage d'urgence 1m
délai_de_contrôle_du_processus 10s

Les deux premiers réglages sont des mises en garde et indiquent à la php-fpm que si dix processus enfants échouent en l'espace d'une minute, le processus principal s'arrête. php-fpm devrait redémarrer.

Cela peut sembler peu robuste, mais PHP est un processus de courte durée qui laisse échapper de la mémoire, et le redémarrage du processus principal en cas de défaillance importante peut résoudre de nombreux problèmes.

La troisième option, process_control_timeoutindique aux processus enfants d'attendre ce laps de temps avant d'exécuter le signal reçu du processus parent. Ceci est utile dans les cas où les processus enfants sont en train de faire quelque chose lorsque le processus parent envoie un signal KILL, par exemple. Avec dix secondes sous la main, ils auront plus de chances de terminer leurs tâches et de sortir de manière élégante.

De manière surprenante, cette n'est pas la viande de php-fpm configuration ! En effet, pour servir les requêtes web, l'option php-fpm crée un nouveau pool de processus, qui aura une configuration distincte. Dans mon cas, le nom du pool s'est avéré être www et le fichier que je voulais modifier était /etc/php/7.2/fpm/pool.d/www.conf.

Voyons comment commence ce fichier :

; Démarrer un nouveau pool nommé 'www'.
; la variable $pool peut être utilisée dans n'importe quelle directive et sera remplacée par ; le nom du pool ("www" ici).
; nom du pool ('www' ici)
[www]

; Par préfixe de pool
; Cela ne s'applique qu'aux directives suivantes :
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values' ; - 'php_admin_values'
; - 'php_admin_values'
; S'il n'est pas défini, le préfixe global (ou /usr) s'applique à la place.
Note : Cette directive peut également être relative au préfixe global.
Valeur par défaut : none
;préfixe = /path/to/pools/$pool

; Utilisateur Unix/groupe de processus
Note : L'utilisateur est obligatoire. Si le groupe n'est pas défini, le groupe de l'utilisateur par défaut
par défaut de l'utilisateur sera utilisé.
utilisateur = www-data
group = www-data

Un rapide coup d'œil à la fin de l'extrait ci-dessus permet de résoudre l'énigme de la raison pour laquelle le processus serveur s'exécute en tant que www-data. Si vous avez rencontré des problèmes d'autorisation de fichiers lors de la création de votre site web, vous avez probablement changé le propriétaire ou le groupe du répertoire en www-datapermettant ainsi au processus PHP d'écrire dans des fichiers journaux, de télécharger des documents, etc.

Enfin, nous arrivons à la source du problème, le paramètre du gestionnaire de processus (pm). En règle générale, les valeurs par défaut sont les suivantes :

pm = dynamique
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

Alors, qu'est-ce que "dynamique"signifie-t-il ? Je pense que c'est la documentation officielle qui l'explique le mieux (je veux dire que cela devrait déjà faire partie du fichier que vous éditez, mais je l'ai reproduit ici juste au cas où ce ne serait pas le cas) :

 ; Choisissez comment le gestionnaire de processus contrôlera le nombre de processus enfants.
Valeurs possibles :
; statique - un nombre fixe (pm.max_children) de processus enfants ;
; dynamique - le nombre de processus enfants est fixé dynamiquement en fonction des directives
; dynamique - le nombre de processus enfants est fixé dynamiquement en fonction des directives suivantes. Avec cette gestion des processus, il y aura ; toujours au moins un
; toujours au moins 1 enfant.
; pm.max_children - le nombre maximum d'enfants qui peuvent ; être en vie en même temps.
; être en vie en même temps.
; pm.start_servers - le nombre d'enfants créés au démarrage.
; pm.min_spare_servers - le nombre minimum d'enfants en état d'inactivité
; "idle" (en attente de traitement). Si le nombre
; de processus "inactifs" est inférieur à ce nombre, des
; nombre, certains enfants seront créés.
; pm.max_spare_servers - le nombre maximum d'enfants en état d'inactivité
; inactifs (en attente d'un processus). Si le nombre
; de processus "inactifs" est supérieur à ce nombre, certains
; est supérieur à ce nombre, certains enfants seront tués.
ondemand - aucun enfant n'est créé au démarrage. Les enfants seront bifurqués lorsque
; nouvelles demandes se connectent. Les paramètres suivants sont utilisés :
; pm.max_children - le nombre maximum d'enfants qui ; peuvent être en vie en même temps.
; peuvent être en vie en même temps.
; pm.process_idle_timeout - Le nombre de secondes au bout desquelles ; un processus inactif sera tué.
; un processus inactif sera tué.
Remarque : cette valeur est obligatoire.

Nous voyons donc qu'il y a trois valeurs possibles :

  • Statique: Un nombre fixe de processus PHP sera maintenu quoi qu'il arrive.
  • Dynamique: Nous pouvons spécifier le nombre minimum et maximum de processus qui peuvent être mis en œuvre. php-fpm restera en vie à un moment donné.
  • à la demande: Les processus sont créés et détruits à la demande.

Quelle est donc l'importance de ces paramètres ?

En termes simples, si vous avez un site web à faible trafic, le paramètre "dynamique" est un gaspillage de ressources la plupart du temps. En supposant que vous ayez pm.min_spare_servers réglé sur 3, trois processus PHP seront créés et maintenus même lorsque le site web n'est pas fréquenté. Dans de tels cas, l'option "à la demande" est préférable, car elle permet au système de décider quand lancer de nouveaux processus.

D'autre part, les sites web qui gérer de grandes quantités de trafic ou qui doivent réagir rapidement seront pénalisés dans ce contexte. La création d'un nouveau processus PHP, son intégration dans un pool et sa surveillance constituent une charge supplémentaire qu'il est préférable d'éviter.

Utilisation pm = static fixe le nombre de processus enfants, ce qui permet d'utiliser au maximum les ressources du système pour répondre aux requêtes plutôt que pour gérer PHP. Si vous optez pour cette solution, sachez qu'elle a ses règles et ses pièges. Un article assez dense mais très utile à ce sujet se trouve à l'adresse suivante ici.

Derniers mots

Étant donné que les articles sur les performances des sites web peuvent déclencher des guerres ou semer la confusion, je pense qu'il convient de dire quelques mots avant de clore cet article. L'optimisation des performances relève autant de la conjecture et des arts obscurs que de la connaissance du système.

Même si vous connaissez tous les php-fpm Le succès n'est pas garanti. Si vous n'aviez aucune idée de l'existence des php-fpmAlors, ne perdez pas de temps à vous en préoccuper. Continuez à faire ce que vous faites déjà et poursuivez votre chemin.

En même temps, évitez d'être un accro de la performance. Oui, vous pouvez obtenir de meilleures performances en recompilant PHP à partir de zéro et en supprimant tous les modules que vous n'utiliserez pas, mais cette approche n'est pas assez saine dans les environnements de production. L'idée d'optimiser quelque chose est de voir si vos besoins diffèrent des valeurs par défaut (ce qui est rarement le cas !), et de faire des changements mineurs si nécessaire.

Si vous n'êtes pas prêt à consacrer du temps à l'optimisation de vos serveurs PHP, vous pouvez envisager de recourir à une plateforme fiable telle que Kinsta qui s'occupe de l'optimisation des performances et de la sécurité.

  • Ankush
    Auteur
Merci à nos sponsors
D'autres lectures intéressantes sur le développement
Alimentez votre entreprise
Quelques outils et services pour aider votre entreprise à se développer.
  • Invicti utilise le Proof-Based Scanning™ pour vérifier automatiquement les vulnérabilités identifiées et générer des résultats exploitables en quelques heures seulement.
    Essayez Invicti
  • Web scraping, proxy résidentiel, proxy manager, web unlocker, search engine crawler, et tout ce dont vous avez besoin pour collecter des données web.
    Essayez Brightdata
  • Monday.com est un système d'exploitation tout-en-un qui vous aide à gérer vos projets, vos tâches, votre travail, vos ventes, votre CRM, vos opérations, vos flux de travail et bien plus encore.
    Essayez le lundi
  • Intruder est un scanner de vulnérabilité en ligne qui détecte les faiblesses de votre infrastructure en matière de cybersécurité, afin d'éviter des violations de données coûteuses.
    Essayer l'intrus