Le lendemain matin, à mon retour, j'ai donc regardé à l'aide de la commande grep
si des verrous étaient posés par les scripts PHP du site d'administration sur la base de données, aussi bien au niveau des tables qu'au niveau des lignes qu'elles contiennent, innodb permettant la pose de verrous à ce niveau notamment pour assurer l'intégrité de la base de données dans un contexte transactionnel.
Par acquis de conscience, j'ai également appliqué la même commande sur le journal de l'ensemble des requêtes SQL effectuées sur le serveur MySQL, activé temporairement pour l'occasion en environnement de pré-production.
Ma recherche n'ayant rien donné et son résultat m'ayant été confirmés par les développeurs du site d'administration qui m'ont assuré que leur code ne posait aucun verrou à ce niveau, j'en ai déduit que ce dernier devait être posé sur un fichier soit par un script PHP, soit par Apache lui-même.
En effet, Apache est installé en mode prefork et il est de plus complété du module mod_itk qui permet d'attribuer un utilisateur et un groupe spécifique pour chaque processus apache correspondant à un site web précis.
Or, pour y parvenir, ce module provoque le fork du serveur apache dans son intégralité lorsqu'il reçoit une requête HTTP afin de pouvoir lui attribuer l'utilisateur et le groupe ad hoc.
Il est donc théoriquement possible que cette stratégie génère une situation de compétition vis à vis d'une ressource commune à l'ensemble des processus et qu'en conséquence, cela provoque le traitement séquentielle des requêtes et donc la baisse de performance constatée.
J'ai donc lancé la commande strace
sur l'un des processus Apache du site d'administration afin de tenter de localiser la ressource concernée.
Cette commande est en effet un outil très puissant dans ce contexte, car elle permet de tracer l'ensemble des interactions entre un programme et le système de l'exploitation qui l'exécute.
Son utilisation m'a donc permis d'avoir la confirmation que nous étions sur la bonne piste, puisque j'ai alors été bombardé de message du type Resources unavailable
, suivi d'un magnifique signal SIGCHLD
indiquant la mort du processus concerné.
Je n'ai cependant pas eu d'indication quand à la nature de la ressource concernée, et j'ai donc alors décidé de demander conseil à des gens disposant de plus de compétences que moi en ce qui concerne l'administration et le fonctionnement d'un serveur Apache.
Un petit tour sur IRC et le canal adéquate (merci au passage aux plieurs de papier, ils se reconnaîtront) suivi d'une modification des règles de pare-feu du mod_status de Apache plus tard afin que mes contacts disposent des informations nécessaires, et j'avais la confirmation du fait que notre serveur HTTP forkait bien comme un malade et que cela pouvait tout à fait expliquer les mauvaises performances de notre solution.
En cadeau bonus, il m'a de plus été fourni deux solutions possibles, à savoir soit virer mod_itk pour revenir au fonctionnement classique de Apache en mode prefork, soit utiliser FastCGI pour gérer les requêtes PHP.
J'ai donc discuter des ces deux possibilités avec l'équipe, et après quelques explications sur leurs avantages et inconvénients respectifs, nous avons décidé de tester l'utilisation de FastCGI avec php-fpm, cette solution présentant en théorie de nombreux avantages, aussi bien en terme de performance que de configuration et de supervision.
En effet, php-fpm permet de définir des groupes de processus pour chacun des sites, groupes qu'il est possible de configurer finement et indépendamment en fonction des besoins, et de plus, son mode de fonctionnement reposant sur FastCGI permet de minimiser les opérations de fork nécessaires au traitement d'une requête HTTP et cette solution est donc plus efficace que le traditionnel couple Apache en prefork et mod_php.
J'avoue avoir pousser relativement fort dans cette direction au cours de la discussion, à la fois parce que je pensais que cela résoudrait notre problème et parce que je voulais depuis longtemps tester cette solution en production et que c'était la première fois que j'en avais l'occasion.
Pour nos tests, nous avons décidé d'utiliser un serveur jumeau de celui de notre client que nous utilisions pour nos besoins internes et que nous pouvions donc arrêter sans soucis le temps d'effectuer les installations et la configuration nécessaires.
Nous avons donc supprimé apache et mod_itk de notre serveur de test et nous avons installé et configuré en lieu et place la triplette Apache, mod_fastcgi et php-fpm et nous avons mis quelques heures à réaliser cela, car si la documentation pour installer tout cela est relativement abondante, elle n'est bien souvent plus à jour et de plus, elle se contente en général d'expliquer la configuration nécessaire pour gérer un seul site et non plusieurs sur un même serveur, d'autant que jusqu'à ce moment, je n'avais jamais mis en production php-fpm, tout comme mon administrateur système.
Cependant, après quelques prises de tête relativement intenses, nous sommes finalement parvenu à trouver une configuration suffisamment générique pour répondre à nos besoins à moindre frais.
Nous nous sommes alors empressé de répliquer les 10 Go de la base de données de production du client sur notre serveur de test, ainsi que les dernières versions du site de e-commerce et d'administration.
Et une fois cela fait, c'est avec jubilation que j'ai appuyer sur la touche F5 de mon clavier pour rafraîchir la page d'acceuil du site de e-commerce…
Et si vous voulez savoir ce qui s'est alors passé, il vous faudra patienter jusqu'au prochain épisode !
13 réactions
1 De Stef - 18/10/2012, 13:59
suspense suspense !
2 De @_dynamicnet - 18/10/2012, 14:20
J'ai hâte d'avoir tes conclusions, je fais tourner php-fpm (avec nginx) en prod depuis plus d'un an et j'en suis très content.
Dans tous les cas merci pour cette série d'article, lecture toujours intéressante.
David
3 De raphaelle - 18/10/2012, 14:28
à la lecture de ces 3 épisodes, je dis qu'en fait c'était pas ça la solution...ce sera autres chose...mais quoi? bon ben on attend le suivant
merci en tout cas!
4 De nico - 18/10/2012, 16:53
Hummm, du même avis que Raphaelle, quelque chose... Sans doute tout bête...
Merci pour les articles
5 De Ascarius - 18/10/2012, 20:27
Rhaaa ! Quel suspense intenable !
On doit pouvoir faire une série télé là dessus...
Je vois bien le fameux (avec une voix grâve) : "Previously in Technical Audit Chronicle"
J'imagine aussi une chute toute conne (ce qui va bien avec une série télé), genre, un pauvre fichier de log.
6 De cydelic - 18/10/2012, 22:52
Argh toujours pas de conclusion :'(
Sinon attention avec mod_fastcgi car il n'est plus maintenu, et n'est plus compatible avec apache 2.4. De plus, si tu utilise mod_fastcgi avec php-fpm, prend bien la version mod_fastcgi 2.4.7 sinon tu risque de perdre des requetes (http://serverfault.com/questions/21...)
7 De Olivier Pons - 20/10/2012, 00:22
Moi je me doute bien du résultat, car j'ai un de mes anciens élèves qui a fait site qui fonctionne bien (en terme de fréquence) et qui a fait un gain de performance extraordinaire aussi bien en rapidité qu'en consommation mémoire
8 De mageekguy - 22/10/2012, 09:47
@cydelic : mod_fastcgi fonctionne très bien avec Apache 2.4…
9 De desfrenes - 22/10/2012, 23:44
Si php-fpm, pourquoi ne pas opter pour nginx ? C'est pas une question rhétorique, c'est pour savoir si des contraintes l'empêchent ou s'il y a d'autres raisons.
10 De mageekguy - 23/10/2012, 12:12
@desfrenes : C'est prévu, mais j'évite en général de modifier plusieurs éléments de la pile en même temps pour résoudre un problème car il est ensuite difficile de définir la ou (pire) les modifications qui ont eu une influence (ou pas), et cela d'autant plus lorsque je ne dispose pas des compétences ad hoc.
11 De desfrenes - 24/10/2012, 10:12
Ok ! On a fait ce switch récemment (nginx + php-fpm), pour l'instant rien à regretter. On a eu une phase de rodage pour adapter correctement les réglages de php-fpm en mode dynamic, mais là c'est ok.
12 De spontexbob - 07/11/2012, 11:14
@mageekguy "Et si vous voulez savoir ce qui s'est alors passé, il vous faudra patienter jusqu'au prochain épisode !"
A quand la suite ?
13 De mageekguy - 07/11/2012, 13:49
@spontexbob : maintenant