Purge sélective avec Drupal des pages mises en cache par Nginx

Serveur Web Nginx

Le serveur Web Nginx dispose d'un système de cache qui permet d'accélérer considérablement la vitesse de chargement des pages de votre site Internet, Drupal ou tout autre CMS, et bien sûr de servir un bien plus grand nombre de visiteurs simultanés. La durée pendant laquelle les pages de votre site sont servies depuis le cache de Nginx, et non depuis une requête sur votre site web, est configurée au niveau du serveur web.

Si le cache de Nginx est paramétré pour une durée de 24 heures, alors toute modification ou ajout d'un contenu, d'un commentaire, etc. ne sera pas visible avant que la version de la page, mise en cache par Nginx, atteigne sa date d'expiration. Ce qui peut être particulièrement problématique en cas de modification ou correction d'un contenu, et encore plus pour les commentaires postés par vos visiteurs, qui ne seront visibles qu'au bout de 24h ou un peu moins.

Heureusement, Drupal dispose de deux modules Cache expiration et Purge qui vont vous permettre de mettre en place très facilement une purge sélective des pages mises en cache par Nginx, ou tout autre reverse proxy cache comme Varnish, dès que celles-ci auront été modifiées, que ce soit par l'ajout d'un commentaire ou par la modification de son contenu.

Cette purge sélective du cache de Nginx permet de mettre en place un macrocache sur une longue durée tout en offrant à vos visiteurs la dernière version disponible de vos contenus.

Quand un contenu est modifié sur le site, comme un article ou un utilisateur, le module Cache expiration va vérifier l'existence de pages relatives à ce contenu (les pages de taxonomy, les alias, les menus) et va donc collecter toutes les autres pages qui ont été modifiées suite à cette mise à jour. Le module Cache expiration supporte le module rules qui peut nous permettre aussi de collecter très facilement d'autres pages impactées par cette mise à jour, notamment par exemple si nous utilisons le module Entity reference plutôt que la taxonomy.

Le module Purge va ensuite se charger de transmettre les adresses des pages collectées au serveur Nginx pour lui indiquer quelles pages il doit purger de son cache.

Il suffit de créer ensuite un nouveau serveur sur Nginx qui va écouter sur un port particulier (au choix) et qui sera chargé de récolter les adresses des url transmises par le module Purge et de les vider du cache.

## Cache purging
## Support for http://drupal.org/project/purge module.
##
## PURGE anonymous cache

server {
  listen 127.0.0.1:6789;

  access_log /var/log/nginx/purge.access.log;
  error_log /var/log/nginx/purge.error.log;
  keepalive_timeout 0 0;

  allow 127.0.0.1;
  deny all;

  location / {
    try_files $uri =404;
  }

  location ~ /purge(/.*) {
    fastcgi_cache_purge YOUR_NAME_CACHE $scheme$host$request_method$1$is_args$args;
  }
}

Dans cet exemple, le serveur va écouter sur le port 6789 les requêtes en provenance du même serveur physique (localhost) et purger les pages du cache dont le nom est YOUR_NAME_CACHE. La clé utilisée pour cacher les pages avec l'instruction fastcgi_cache_key correspond à $scheme$host$request_method$request_uri.

Il faudra alors renseigner, dans les paramètres du module Purge, l'adresse à laquelle il doit envoyer la liste des pages à purger. Dans notre exemple, http://localhost:6789/purge?purge_method=get

Nous disposons maintenant d'un cache longue durée sur notre serveur Nginx qui sera purgé automatiquement et sélectivement dès qu'un contenu sera mise à jour. A noter que Nginx doit disposer du module cache-purge disponible dans le package nginx-extras sur dotdeb.org, et que php-curl doit être installé sur votre serveur.

La mise en place d'un cache longue durée sur un site complexe doit être analysée en détail sur ses avantages/inconvénients. En effet, si l'arbre des dépendances est trop important et que vous deviez au final invalider le cache de la plupart des pages de votre site Drupal, il vaut mieux dans ce cas implémenter la technique du microcache qui consiste à mettre en cache les pages pour une durée très courte, quelques minutes tout au plus.

Alimentation du cache aux heures creuses

Afin de proposer systématiquement des pages mises en cache (et donc beaucoup plus rapides) pour le confort de vos visiteurs, vous pouvez alors alimenter le cache de Nginx avec toutes les pages de votre site, durant ses heures creuses, en utilisant le script ci-dessous. Ce script s'appuie sur le fichier sitemap.xml que vous n'avez pas manqué de générer afin de le soumettre aux moteurs de recherche.

#!/bin/bash

# Si l'argument n'est pas passé, on arrête
if [ $# -ne 1 ]
then
        echo "Vous n'avez pas fourni l'adresse du site à parcourir"
        echo "usage : ./cache_warming.sh MONDOMAINE.FR"
        exit 1
else
        URL=$1
fi

wget --quiet http://$URL/sitemap.xml --output-document - | egrep -o "http://$URL[^<]+" | while read line; do
  curl -A 'Mozilla/5.0 (X11; Linux x86_64)' -s -L $line > /dev/null 2>&1
  echo $line
done

Vous pouvez alors configurer votre cron :

crontab -e

0 2 * * * /home/script/cache_warming.sh MONDOMAINE.FR

Besoin d'aide pour mettre en place une purge sélective du cache de Nginx ? Laissez un commentaire ou contactez moi.

Ajouter un commentaire