web-dev-qa-db-fra.com

Problème de performances: retard à la première demande

J'ai monté un site D7 avec un sous-thème Minelli. En cours de route, j'ai beaucoup expérimenté avec différents thèmes, différents modules. Quelque part en cours de route, j'ai développé un problème de performance étrange, et maintenant je ne sais pas vraiment quel thème/module/config l'a causé.

Le problème est que lorsque je visite le site pour la première fois, il faut environ 15 secondes avant que la première page ne s'affiche. Je peux alors me déplacer sur le site et il est très réactif. Si je le laisse pendant environ une heure, puis y reviens, la première demande est à nouveau très lente.

J'ai effacé le cache de sorte que cela ne devrait pas être le problème. De plus, j'ai désactivé des thèmes et des modules que je n'utilise pas. J'ai déplacé le site vers une nouvelle infrastructure mais le problème l'a suivi!

Où dois-je aller ensuite?

37
Kim Prince

Il y a trois choses que je voudrais vérifier.

Premièrement, si vous êtes sur un site de production et ne modifiez pas les fichiers PHP, alors vous devez vous assurer que APC est activé, a suffisamment de mémoire et a une longue TTL = (vous pouvez choisir une journée ou ne jamais expirer si vous le souhaitez.) Vous pouvez également envisager de définir apc.stat=0. Les APC docs ont toutes les informations dont vous avez besoin pour configurer le TTL. Pour choisir la quantité de mémoire, vous devez coller le fichier apc.php dans un endroit protégé et surveiller l'utilisation de la mémoire et les statistiques de désabonnement. Ajustez la mémoire APC pour que votre taux d'échecs soit très bas. La lenteur initiale pourrait être due au fait qu'APC est plein et se vide (IIRC, APC vide tout le cache lorsqu'il est plein au lieu d'utiliser LRU ou des stratégies de cache plus avancées).

Deuxièmement, assurez-vous que MySQL est réglé correctement. Vous pouvez utiliser mysqltuner pour ajuster la taille de vos tampons. Votre lenteur initiale pourrait être due au chargement de tables à partir du disque et/ou des échecs du cache de requête. Bien qu'il ne soit pas parfait, mysqltuner vous fait avancer dans la bonne direction.

Troisièmement, assurez-vous d'avoir une véritable stratégie Cron Drupal . Personnellement, je désactiverais le cron automagique sur "admin/config/system/cron" et mettrais en place un crontab pour qu'il s'exécute chaque nuit. Vous pouvez également essayer Elysia Cron si vous avez vraiment besoin d'un contrôle plus fin sur les choses. De cette façon, vous pouvez exécuter les tâches nécessaires aussi souvent que nécessaire, mais faire exécuter les tâches normales pendant la nuit. Votre lenteur initiale pourrait provenir de cycles cron qui se produisent toutes les heures. Vous pouvez le confirmer en regardant quand cron s'exécute sur "admin/reports/dblog" et en essayant de correspondre à votre lenteur.

16
mpdonadio

Ivanhoe123 a probablement raison: Drupal 7 est livré avec 'pauvre mans cron' activé par défaut. En bref, cela signifie que (de temps en temps) cron est exécuté avant Drupal rend la page, retardant tout.

Essayez toujours d'utiliser un vrai travail cron sur les sites de production. Pour plus de détails techniques, voir http://drupal.org/cron , ou parlez à votre hébergeur.

Pour le désactiver, accédez à admin/config/system/cron et sélectionnez "Jamais".

9
Attiks

Le module Devel offre une journalisation de la base de données pour vérifier si vous avez des requêtes longues.

Si cela n'aide pas, prenez XHProf ou XDebug et trouvez le code coupable. XHProf (un profileur) vous trace une belle carte de toutes les fonctions en cours d'exécution sur le serveur et vous indique celles qui consomment le plus de temps d'exécution. D'un autre côté, lorsque XDebug (un débogueur) est configuré avec un IDE tel que Eclipse ( voir la vidéo ), il vous permet d'explorer chaque fonction en cours d'exécution LIVE Le profileur vous donnera une idée de ce que est en cours d'exécution, tandis que le débogueur vous montrera pourquoi est-il en cours d'exécution.

8
BetaRide

Juste de la saveur de la question, je pense immédiatement à trois (3) choses

  • Moteur de stockage MySQL/CPU
  • Mise en cache de la base de données
  • Verrouillage de table

Moteur de stockage MySQL

Si vous n'utilisez aucune recherche/indexation FULLTEXT, je vous recommande fortement de convertir toutes vos données MyISAM en InnoDB. MyISAM n'est pas conçu pour tirer parti de plusieurs processeurs et cœurs multiples. InnoDB a été considérablement amélioré pour l'utilisation de plusieurs processeurs ainsi que pour l'hyperthreading en lecture/écriture.

Voici quelques articles que j'ai faits à ce sujet dans le DBA StackExchange et sur ce site en ce qui concerne le réglage de MySQL pour InnoDB Performance

Mise en cache de la base de données

Un autre argument solide pour convertir toutes les données MyISAM en InnoDB est la façon dont MySQL met en cache les données/index. Le moteur de stockage MyISAM ne met en cache que les index. InnoDB met en cache les données et les index . À la lumière de cela, vous pouvez allouer suffisamment de mémoire pour le pool de mémoire tampon InnoDB pour accueillir l'un des éléments suivants (le plus petit des deux)

  • Toutes les données et tous les index InnoDB (Idéal si vous en avez assez RAM pour cela aussi pour l'OS; élimine les retards ultérieurs))
  • 75% des installés RAM (dans le cas où vous avez plus de données/index InnoDB que RAM; minimise les retards))

Si vous utilisez MySQL 5.1, vous pouvez définir innodb_max_dirty_pages_pct = 0. Cela augmentera légèrement les E/S du disque, mais le Le pool de tampons InnoDB sera suffisamment effacé pour permettre aux anciennes pages de données et d'index de pivoter sans surtensions d'E/S disque. MySQL 5.5 et le plug-in InnoDB de MySQL 5.1 n'ont pas besoin de cet ajustement car il dispose d'un meilleur mécanisme de vidage du pool de tampons par défaut.

Si utiliser InnoDB est hors de question, vous devrez peut-être aller avec memcached ou vernis. Cela permet au développeur de dicter la durée de conservation des données mises en cache dans la RAM du serveur. Naturellement, cela nécessitera une amélioration du développement pour rendre votre application compatible avec le memcached/le vernis.

Verrouillage de la table

Épilogue

Vous ne pouvez pas éviter un retard initial après un redémarrage de MySQL. Pourtant, une fois que vous avez amélioré MySQL en utilisant les suggestions/informations susmentionnées, vous ne devriez plus subir de retards ultérieurs.

6
RolandoMySQLDBA

J'utiliserais des outils comme YSlow ou Firebug etc. pour déterminer exactement ce qui se passe lorsque vous chargez ladite page et quand vous chargez ladite page immédiatement après. Vérifiez s'il s'agit d'un problème de mise en cache et, en outre, vérifiez comment il fonctionne lorsque vous accédez à la page en tant qu'utilisateur anonyme, puis en tant qu'utilisateur authentifié. Comparez cela à vos paramètres de performances dans Drupal.

Si ce n'est pas un problème de mise en cache, utilisez le journal des requêtes de Devel ainsi que les journaux de MySQL pour voir ce qui se passe avec w.r.t. la base de données. De plus, si vous avez un opcode ou des caches améliorant les performances similaires sur le serveur, essayez de supprimer certains nombres puis de les réactiver.

5
user7667

On dirait que le cron fonctionne.

Vérifiez vos paramètres ici: admin/config/system/cron

4
Aram Boyajyan

Beaucoup de gens suggèrent que ce problème pourrait être lié au blocage des processus d'arrière-plan synchrones , en particulier lié aux tâches cron lourdes .

Si cela est vrai, il existe une grande paire de modules en développement actif par gielfeldt * qui pourrait résoudre ce problème immédiatement, ou au moins, pourrait offrir des indices et aider les constructeurs de sites à diagnostiquer et traiter des coupables spécifiques dans leur cas. Les deux remplacent les processus synchrones bloquants par des commandes ou des codes HTTP asynchrones non bloquants, et offrent tous deux des rapports pertinents qui peuvent identifier les processus gênants:

  • Processus en arrière-plan et ses modules fournis permettent à la file d'attente des processus en arrière-plan de Drupal d'être traitée de manière asynchrone, afin qu'ils ne se bloquent pas. Cela pourrait arrêter le problème. En outre, avec le module Apache Server de processus d'arrière-plan fourni dans la dernière version, il existe un rapport d'interface utilisateur basique mais amélioré avec des fonctionnalités pour superviser, déverrouiller et inspecter les heures de début et la progression de ces processus. Cela pourrait identifier le processus de problème.
  • ltimate Cron s'appuie sur le processus d'arrière-plan pour permettre aux tâches déclenchées par cron d'avoir leurs propres scehdules asynchrones séparés, chacun pouvant être surveillé et arrêté dans une interface utilisateur. En plus d'être idéal pour séparer les tâches lourdes de réduction des performances du nettoyage régulier à faible surcharge, il vous fournit également un rapport avec des informations pratiques telles que la durée d'exécution de chaque tâche déclenchée par cron individuelle, lors de leur dernière exécution, l'état actuel, etc. Cela pourrait également supprimer le blocage et/ou identifier les processus problématiques.

Les deux sont de toute façon des modules très utiles; pour ce problème, ils peuvent être utilisés pour tester la théorie (de sondage très plausible) selon laquelle les blocages sont causés par des processus de blocage synchrones ou des exécutions cron. Potentiellement, ils pourraient résoudre le problème en les exécutant de manière asynchrone plutôt que synchrone, et ils pourraient également offrir des indices sur les processus spécifiques à l'origine du blocage. (sachez que leur documentation est un travail en cours ...

Si, cependant, ils ne peuvent pas être configurés pour aider du tout, cela suggère que le problème ne se limite pas aux processus d'arrière-plan synchrones. FWIW, je n'ai jamais eu ce problème particulier sur un site depuis que ces modules fonctionnent correctement (pourtant - touchez du bois) - mais je l'ai déjà vu sur mes sites, ainsi que sur des sites en direct Drupal dans la nature.

Soyez également au courant des autres modules plug-in connexes actuellement en développement - par exemple dans les cas complexes de haute intensité, ltimate Cron Queue Scaler , qui permet une limitation basée sur les seuils, peut aider à réduire les problèmes de performances liés au cron.


* pas d'affiliation, je suis juste un utilisateur très impressionné de leur travail

3

J'ai presque abandonné Drupal pour mon dernier projet à cause de cela.

Il me faut cependant plus d'une cause. Je n'ai pas encore trouvé de solution "tout réparer" qui fonctionne à chaque fois que ce problème se pose.

Syslog et Ubuntu/Debain

La première fois que j'ai parcouru le temps de chargement intermittent de 15 secondes, c'était en exécutant drupal sur les systèmes Debian/Ubuntu (dédiés, non partagés). Désactivation du module Syslog était la solution pour moi.

Comme l'a dit @BetaRide, l'utilisation de xDebug ou d'un autre PHP profiler est extrêmement instructif.


Toujours un problème - une solution de contournement

Quant à mes autres installations, je suis toujours perdu.

Ce problème est plus visible sur mon serveur de développement et mon faible trafic Drupal installe.

Comme solution de contournement, j'ai configuré un travail cron pour charger la page d'accueil du site toutes les 60 secondes ainsi que le script cron de Drupal toutes les 300 secondes. Ce n'est évidemment pas optimal, mais je préfère wget ou curl vivre le temps de chargement de 15 secondes au lieu d'un visiteur humain.

3
Citricguy

Comme cela me frappe une fois de plus, je commence à enquêter sur le problème. Je peux certainement confirmer que

  1. un appel à drupal_cron_run() déclenché par le cron de core de poorman ajoute ~ 5s au temps de requête sur ma machine de développement. Cela peut être testé en décommentant les tests autour de l'appel à drupal_cron_run() dans modules/system/system.module Dans system_run_automated_cron()
  2. effacer tous les caches ajoute environ 2 secondes au temps de demande sur ma machine de développement. Cela peut être testé en faisant un drush cc all Et en rechargeant à nouveau la page.

Cela signifie que définir cron sur jamais et ajouter un appel à cron via crontab améliore considérablement la situation. Frapper quelques pages souvent utilisées juste après pour recharger le cache améliorerait à nouveau l'expérience utilisateur.

Je ne suis pas sûr cependant de la mise en cache. Je n'ai pas touché aux paramètres de cache par défaut de ce site. Je pense que drupal reconstruit tous les caches de temps en temps peut-être déclenché par cron, mais je ne sais pas comment cela se fait. Mais un délai de 7 secondes est à peu près ce que je vois quand je frappe la page après quelques heures.

2
BetaRide

Quelqu'un a mentionné que GoDaddy sera lent. De nombreuses sociétés d'hébergement basées sur le cloud auront également ce délai initial car des services comme AWS l'ont. Il est moins cher d'avoir des serveurs automatiquement priorisés, et ces serveurs auront besoin d'une seconde ou deux pour se "réveiller".

Par exemple, Pagodabox a 3-4 secondes pour le premier octet, jusqu'à ce que le serveur soit joyeusement réveillé. Pagodabox a en fait monétisé en gardant le serveur éveillé, et vous pouvez donc payer un supplément pour "caffiéner" votre site.

De plus, un CDN peut vous aider. Votre serveur Web/DB ne sera pas chargé avec la diffusion des pages ou des images en cache. Un bon tutoriel ici: http://wimleers.com/article/easy-drupal-cdn-integration-for-fun-and-profit

Et ... WebPageTest me fait plaisir. http://www.webpagetest.org/ Comparez gratuitement les temps de chargement sur la planète et avec différents navigateurs Web. Utilisez-le pour obtenir des résultats concrets quelles que soient les modifications que vous apportez.

1
paul-m

Vérifiez que vous n'avez supprimé aucun module sans les désinstaller. Cela provoque un retard car Drupal essaie de trouver les fichiers mais ils ne sont plus là.

Supprimez les références dans le tableau des variables si les modules n'existent plus.

1
cateye

Un APM Web tel que newrelic est le meilleur outil pour détecter les problèmes de performances. J'ai eu des sites appelant une ou deux lignes de code qui faisaient des choses loufoques, chargeaient des tableaux inutiles à des moments étranges et faisaient d'autres choses qui étaient assez invisibles jusqu'à ce que nous les traquions avec un APM.

1
beth

Des problèmes comme celui-ci peuvent vous rendre fou et, lorsque j'étais dans des situations similaires, aide à comprendre ce qui provoque le problème une étape à la fois, puis à le tester en tant qu'utilisateur anonyme et connecté. (méthode de la couche d'oignon)

Vous mentionnez que vous commencez à remarquer le problème après avoir joué avec un couple de thèmes et un codage personnalisé. Je ne sais pas à quel point votre site est complexe ni la logique derrière, mais les étapes suivantes vous aideront à trouver le problème:

  1. Dans votre serveur, créez un dossier ou un autre compte (cela pourrait être mieux) où vous allez faire une installation propre Drupal installer avec la même version que vous utilisez sur votre site. Puis sans ajouter de module ou un thème teste le temps nécessaire au site pour répondre à la première demande et à la demande suivante. Si tout fonctionne bien, vous pouvez ignorer les problèmes de configuration du serveur, s'il se comporte de la même manière que votre actuel, vous avez une erreur de configuration soit avec votre site Web serveur ou base de données.

  2. Si les résultats de l'étape 1 sont bons et que le serveur répond rapidement et que les demandes suivantes sont aussi rapides, installez uniquement le thème de votre site actuel sur le site d'installation propre et testez-le à nouveau. Si tout répond toujours rapidement, alors votre thème n'est pas le problème et vous devez continuer à l'étape 3 sinon vous devez commencer à déboguer votre thème * 1.

  3. Si, après les tests de l'étape 2, le site commence toujours à importer rapidement les modules de votre site actuel et assurez-vous de tester le temps de réponse après avoir ajouté et activé chaque module * 2.

  4. Si après avoir ajouté le thème et les modules, le site répond toujours rapidement, ajoutez la configuration, créez des types de contenu, importez des vues, des menus de configuration, etc. N'oubliez pas de tester la réponse du site après avoir ajouté chacun.

  5. L'installation et la configuration sont prêtes et le site encore rapide, et bien apportez maintenant les données. Importer des nœuds, des termes de taxonomie, des commentaires, etc. Je sais que je dois sonner comme un enregistrement cassé, mais toujours tester après avoir terminé chaque étape.

* 1 Test des thèmes: ce processus peut être délicat dans un thème super élaboré, voici quelques conseils:

  1. Si vous vous connectez à une bibliothèque js ou css externe, essayez d'utiliser une copie locale de la même.

  2. Dans votre fichier template.php, vérifiez la fonction qui peut avoir des boucles plus longues ou sans fin ainsi que les fonctions de fonction de prétraitement et/ou de crochet.

  3. Vérifiez un autre fichier de modèle (page.tpl.php, etc.) et recherchez le traitement brut PHP des tableaux et des objets).

  4. Si vous utilisez des "Vues" et des fichiers de modèles de vues, vérifiez-les également.

  5. Vérifiez toujours les chemins, optimisez les images, les fichiers js et css. Parfois, les fichiers js peuvent avoir une certaine hauteur lors de l'utilisation de plusieurs extraits de code dans un seul fichier.

* 2 modules de test: les modules de test sont un peu différents car l'utilisation de manipulations lourdes avec PHP est autorisée. Voici quelques pointeurs:

  1. Les modules pris en charge par la communauté (CCK, Views, etc.) ont une file d'attente de problèmes sur drupal.org, vérifiez-les pour voir s'il existe un problème concernant votre problème et s'il y a des chances qu'il y ait un correctif pour le résoudre.

  2. Propre module codé personnalisé, eh bien si vous avez codé, vous devez le réparer, non?. Vérifiez votre codage et vérifiez l'utilisation des fonctions par rapport à api.drupal.org, vous utilisez peut-être une fonction de surpuissance au lieu d'un crochet.

  3. Module de code personnalisé partagé sur Internet, procédez comme à l'étape 2, mais cette fois, vous pouvez également contacter le rédacteur du module d'origine et lui faire part du problème.

  4. Si votre site est une mise à niveau (D5 -> D6 -> D7) vérifiez les scripts de migration ou de mise à niveau (généralement dans le fichier module.install), vous pourriez avoir besoin d'un "index" supplémentaire sur la nouvelle configuration de table pour accélérer la requête SQL lente X .

  5. Si vous pensez avoir une vision tunnel du problème, sortez un peu et faites une autre activité complètement indépendante, puis revenez plus tard pour réexaminer le problème.

  6. Si vous pointez le problème sur une section de code, mais que vous ne parvenez pas à résoudre le problème, essayez d'expliquer ce que cette section est censée faire à une personne qui ne sait pas comment programmer ou comment Drupal fonctionne et soyez prêt à être surpris.

Remarque: Ne vous inquiétez pas si, après avoir reconstruit votre site, tout commence à fonctionner comme un charme qui est l'une des meilleures fonctionnalités des ordinateurs.

1
Emil Orol

le problème pourrait être n'importe où.

  1. Assurez-vous que vous n'avez activé le mode débogage sur aucun thème ou module. Par exemple, dans de nombreux thèmes, il existe une option pour régénérer le registre de thèmes.
  2. Si vous utilisez un hébergement partagé comme Godaddy, alors 15 secondes pour la première fois est normale.
  3. Convertissez votre site ou votre page d'accueil en base de code à l'aide de module d'exportation Drush CTools . Cela éliminera tout appel à la base de données et votre site fonctionnera entièrement à partir de php.
  4. Si vous rencontrez toujours des problèmes, utilisez les paramètres Devel en activant query log et page timer options sur admin/config/development/devel. Voyez lequel des deux prend plus de temps pour générer la page entière.
  5. Redémarrez votre serveur si rien ne fonctionne.
  6. Installation dans le pire des cas XHProf pour voir où les choses tournent mal.
0
Minty

Je suggérerais d'utiliser un cache frontal sur le modèle du module Boost (en supposant que vous êtes sur un hébergement partagé) ou Varnish. Cela fonctionnera mieux si les accès à votre site sont principalement anonymes et que le contenu de la page est, pour la plupart, non dynamique (c'est-à-dire que les pages ne changent pas beaucoup).

Ces solutions enregistrent les pages rendues lors du premier accès, puis servent le code HTML pré-rendu au lieu de passer par le processus d'amorçage complet Drupal, la création de pages et les thèmes, économisant BEAUCOUP de temps, en particulier sur des sites très fréquentés mais aussi sur des sites comme ceux que vous décrivez qui "s'endorment" et mettent trop de temps à se réveiller.

Le seul véritable inconvénient est que (au moins pour Boost), vous devrez vider le cache lorsque le contenu du site change. Si vous voulez vous assurer que le site est entièrement mis en cache avec le contenu actuel, vous pouvez exécuter drush cc all puis boucler ou wget contre le site complet périodiquement via cron.

0
jmarkel

Voici donc comment j'ai résolu le problème pour mon installation. Ce n'est pas une vraie solution car je n'ai pas pu déterminer la source exacte du problème (s'il y en a un), mais c'est une bonne solution

1) CSS agrégé (paramètres de cache). Cela a réduit la latence de moitié

2) Définissez cron sur jamais (et exécutez-le en externe) - Remarque: j'ai eu des erreurs "essayant de démarrer cron alors qu'il est déjà en cours d'exécution". Je pense qu'il essayait de démarrer cron à chaque lancement mais comme il a échoué, la page cron ne mentionnait pas la dernière tentative, mais plutôt le dernier succès.

3) Configurer une tâche cron qui appelle la page d'accueil avec Lynx toutes les 30 minutes

Tout cela sur un serveur d'hébergement partagé. Ce n'est pas optimal mais ça marche

0
znat