Aller au contenu

Sujets conseillés

Posté

Salut,

Voilà, je voudrais quelques conseils concernant la création d'un système de cache en PHP (je ne compte pas utiliser de systèmes pré-construit car je dois l'utiliser sur un hébergement mutualisé et que je doute des possibilités d'installation) :

Comment faire pour que :

- le serveur gère comme il faut la "if modified since" "last modified" sur une page qui est du php ?

- le serveur compresse les outputs en gz, même lorsqu'il reprend la page en cache ?

- il puisse y avoir des exceptions concernant les pages contenant des formulaires ?

Merci

Posté

Hello,

j'ai du mal à comprendre exactement ce qui pose soucis dans tes questions, mais je vais tenter de ne pas trop répondre à coté de la plaque :D

Déjà il faut bien faire la distinction entre les différents cache. Coté PHP les 3 principaux qu'on croise sont :

- le cache du navigateur (géré à coup de "ETag", de "LastModified" et de "Expires") : cela permet de faire quelques économies de ressource coté serveur et améliore grandement la "sensation de vitesse" pour l'internaute. La page n'est pas re-téléchargée, et généralement pas réinterprétée non plus. Dans le cas de Firefox il peut même être possible de ne pas avoir à ré-exécuter le JS. D'un point de vue utilisateur, c'est pour moi le cache le plus efficace.

- le cache de données (qui consiste à stocker le résultat d'un traitement sous forme "serialisée" ; typiquement une grosse requête). L'avantage c'est qu'il est très souple/modulaire et peut être intégré à tous les types de page de manière plus ou moins complexe. En solution toute prête, il me semble que "Cache_Lite" fait ça.

- le cache de rendu (c'est à dire le code HTML généré par les scripts). C'est de loin le moins souple mais le plus efficace : souvent il se base uniquement sur l'URL pour générer une "clé" et durant N secondes le contenu d'un fichier statique sera directement retourné à l'utilisateur plutôt que d'exécuter les traitements habituels. En solution toute prête, il y aurait JPCache qui faisait ça, et sa soit disant "évolution" QuickCache.

Généralement les caches de rendus se chargent aussi de gérer le cache du navigateur, mais ça n'a rien d'obligatoire. Sur mes sites par exemple je gère systématiquement le cache du navigateur, et sur certains sites/pages j'utilise un cache de données.... mais jamais de cache de rendu par exemple.

Donc toi, tu cherches quelle solution au juste ?

Pour ta première question, il s'agit de gérer correctement le cache navigateur.... et pour les scripts PHP, ça ne se fait pas de manière automatique. C'est donc à tes scripts de prendre ça en charge. Dès lors que tu as la date de dernière modification c'est très simple à mettre en place (ça se fait en 3/4 lignes de code) mais le plus difficile est d'obtenir cette info justement.

Les caches de rendus se basent alors sur l'heure de création du fichier de cache pour gérer le LastModified... et parfois sur le contenu de ce fichier de cache pour générer un checksum et ainsi gérer l'entête ETag.

Pour ce qui est de la compression, elle n'intervient aucunement là dedans... Ormis éventuellement JPCache qui stockait la version compressée de la page afin de ne pas avoir à recompresser systématiquement. Perso je préfère laisser cette tâche à la compression interne de PHP (zlib.output_compression) qui fait ça très bien et sans devoir attendre la fin de la page.

Pour ce qui est des "exceptions", c'est faisable dans tous les cas.

Posté

Alors, je détaille :

  • le site concerné est en php, et le contenu de chaque page est le résultat de requètes base de données pour la récupération du contenu
  • le contenu de chaque page ne change pas trop couramment, c'est pourquoi je souhaite optimiser les traitements côté serveur (interprétation php, requètes sql ...)
  • je voudrais aussi que la page ne soit pas refournie si elle n'a pas changé depuis la dernière visite
  • et qu'elle soit compressée en sortie SI elle doit effectivement être envoyée au client

Sauf erreur de ma part (c'est la première fois que je gère le cache) :

  • pour les 2 premiers points, ça se gère en créant une version "préinterprétée" de la page côté serveur, afin de minimiser les appels réels à la page php. J'avais pensé simplement effacer le fichier de cache concerné lorsqu'un page est modifiée. Ainsi, il devrait la re-créer et la refournir.
  • pour le point "modification depuis la denrière visite", j'ignore comment ça se gère
  • pour le point compression, il faut a priori activer zlib.output_compression, mais est-ce que ça n'a pas un "ordre" d'exécution par rapport à la façon dont le cache serveur agit ?

Merci pour ton aide

Posté

Ce serait donc un cache de "rendu". Si tu veux le faire toi même, c'est à coup d'ob_start() / ob_get_contents() / file_flush_contents pour l'écriture, puis readfile() pour la lecture. Un simple filemtime() servira à vérifier l'existence et la durée de cache.

Pour le coté "modification depuis la dernière visite", en fait le navigateur envoi le contenu du dernier "LastModified" qu'il a reçu. Il te suffit de comparer cet entête avec la date de ton fichier de cache, et basta.

Pour ce qui est de la compression, il n'y a rien de spécial à faire non... Ormis de penser à la désactiver en cas de réponse 304 (à cause d'un "bug" de PHP).

PS : ça c'est pour la version "full" PHP. L'idéal étant de générer un fichier 100% statique, et de ne faire appel à PHP qu'en cas de d'erreur 404.

Posté
PS : ça c'est pour la version "full" PHP. L'idéal étant de générer un fichier 100% statique, et de ne faire appel à PHP qu'en cas de d'erreur 404.

Lorsque je crée un système de cache, je ne me base pas sur une éventuelle panne du serveur PHP, mais éventuellement de la base SQL (plus fragile à mon goût).

Comment gères-tu une panne d'Apache ? Tu mets tous tes fichiers "cachés" à la racine ?

Posté

Là j'avoue que je ne vois pas du tout ce que tu veux dire.

Le principe est le suivant : imaginons que l'internaute demande au serveur la page /bidule/truc.html .

Tu as deux cas :

- elle n'existe pas : le serveur déclenche une erreur 404, et par configuration tu peux lui demander d'appeler un script PHP. Si ce script PHP estime que "bidule/truc.html" correspond effectivement à un contenu, il va créer le fichier /bidule/truc.html et retourner un code 200 ainsi que le contenu de ce fichier.

- elle existe : le serveur retourne directement cette page, tout en gérant comme il se doit les divers entêtes HTTP et la compression à la volée.

C'est plus complexe à mettre en place, n'est vraiment pas adapté aux sites très dynamiques de type forum ou personnalisés en fonction de l'utilisateur, mais le gain de performances n'a vraiment rien à voir avec ce qu'on peut obtenir en se basant uniquement sur PHP.

Mais le but ici est clairement les performances, pas de contourner un problème Apache, PHP ou encore MySQL.

Pour masquer les problèmes de MySQL, j'utilise un simple cache de données.

Pour contourner les problèmes de PHP, j'ai FCGID qui envoi une page 500 personnalisée.

Pour contourner les problèmes d'Apache, j'ai NginX en front qui envoi une page 503 personnalisée.

Posté

En fait, ce que je fais est sensiblement différent :

- via htaccess, je détourne toute demande de fichier .html vers une page de traitement.

- cette page vérifie la présence du fichier dans mon répertoire cache, et sa date. Si le fichier n'existe pas ou est trop vieux, on le regénère et on le crée. S'il existe, on se contente de l'afficher.

Posté

Oui donc méthode "classique" (que j'utilise également hein), le soucis étant que dans ces cas là tu utilises PHP "pour rien".... et justement c'est très lent.

Essaye de faire un simple benchmark sur un fichier HTML statique puis sur un fichier PHP contenant uniquement ce code HTML (sans le moindre tag PHP) ; la différence est énorme.

Posté

Ca, ça dépend de la taille du site... arrivé à un certain trafic, quand on loue déjà plusieurs serveurs à 500 HT/mois chez OVH, il faut commencer à se poser ce genre de questions :D

Il est évidement que si un "SP Mini" suffit pour le site, ce n'est pas non plus la peine de se prendre le chou avec des techniques "complexes".

Posté

C'est pour le boulot, donc je pense que le serveur est correctement dimensionné (même si je n'en connais pas les spécifications).

Les sites génèrent entre 2 et 4 000 visiteurs/jours, et contiennent une bonne dizaine de milliers de pages.

Posté
- le cache de rendu (c'est à dire le code HTML généré par les scripts). C'est de loin le moins souple mais le plus efficace : souvent il se base uniquement sur l'URL pour générer une "clé" et durant N secondes le contenu d'un fichier statique sera directement retourné à l'utilisateur plutôt que d'exécuter les traitements habituels.

J'avais mis en place une technique simple de cache de rendu à base de

Si tu veux le faire toi même, c'est à coup d'ob_start() / ob_get_contents() / file_flush_contents pour l'écriture, puis readfile() pour la lecture. Un simple filemtime() servira à vérifier l'existence et la durée de cache.

Plus simple que ça tu meurs... sauf qu'au moment des pics de fréquentation la charge serveur a tendance à s'emballer et le serveur à swapper sur le disque...

Le remède a été bien pire que le mal.

Posté

Avec 4'000 vu par jour, c'est clair qu'on a pas à se poser ce genre de questions... Mais avec 400'000 ça peut.

ams51 : yep c'est bien pour ça que je n'utilise pas de cache de rendu. J'ai un client qui avait pas loin de 20Go de fichiers servant à son cache de rendu... le serveur passe plus de temps à écrire sur le disque qu'autre chose.

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...