Explication de la situation:
J'étais autrefois sur un serveur mutualisé. Ayant trop de problème de panne du site pour diverses raison, j'ai décidé de passer sous un Serveur Virtuel Privé (VPS).
Depuis le transfert, plusieurs utilisateurs de mon site ce sont plain que certaines pages prennaient un temps fou à charger. Selon les statistique de génération de la page au bas du site, il arrive parfois qu'un page prenne plus de 300 secondes à générer (pire cas: 560 secondes!). Attention, je dis bien GÉNÉRER, et non pas 'chargé sur une connexion lente'.
Recherche du problème:
Le premier truc qui me viend à l'esprit est qu'il y a un problème avec MySQL: certaines requêtes sont probablement très lente considérant qu'il y a une table de 400mb de données. Ayant une fonction qui gère toutes mes requêtes afin d'en tirer des statistiques, je me rend rapidement compte que toutes mes requêtes sont rapides. optimisable peut-être, mais rien qui ne passe proche de justifier une page qui prend 560 secondes à générer: toutes mes requêtes sont traité en moins d'une seconde.
Je me dis alors que peut-etre que MySQL entre en "collision" car il recevrait deux requête en même temps. Je créer donc un système qui Garde en mémoire toutes les requêtes et le temps pour chaqu'une d'elle. À la fin de la page, si le temps de génération de la page dépasse 60 secondes, je recois le rapport par courrier. Rien, je recois des rapports mais toutes les requêtes sont rapides. Le temps est perdu ailleurs.
Je place donc des 'affichage de temps' un peu partout dans mon code. La lenteur proviend de la boucle qui génère la liste des messages.
Je décide donc de retirer tout les ECHO de la boucle et de tout placer le contenu à mettre sur la page dans un buffer. Et de faire:
echo $he_buffer;
après la boucle seulement. La boucle se fait maintenant en un temps éclair mais je continue de recevoir des rapports de page lente par email. Je place donc un affichage de temps avant et après le echo $he_buffer.
$avant = $timer->finish();
echo $he_buffer;
$apres = $timer->finish();
$avant retourne 0.3
$apres retourne des trucs immenses comme 350.424 par exemple.
Donc le echo prend un temps fou à traiter. Il est vrai que $he_buffer contiend parfois jusqu'à 250Kb de texte mais de la à prendre 5 minutes...
Solutions tentées:
- Contacter le support technique de mon fournisseur VPS. Rien de leur coté, ils ont placé le site sur un dual Xeon 3ghz avec 8gb de ram, le problème persiste.
- Remplacer le echo par un print
- Placer des appel à la fonction flush() avant et après le echo
- Monter le paramêtre memory_limit à 20M dans la configuration de PHP
- Re-vérifier le code plusieurs plusieurs fois avec plusieurs personnes différentes. Le code est bon (et fonctionnais bien avant)
- Recompiler Apache et PHP dans le WHM. la version de PHP à été mise à jours (5.1.4).
Avez-vous des pistes (ou mieux, des solutions) ???
Partager