Varnish : mettre en cache tout le contenu public
Posté le Thursday 21 June 2012 | Catégories : Linux, Ubuntu, PHP, Optimisation
Varnish est un accélérateur web (aussi appelé reverse proxy), qui stocke dans un cache les éléments (pages html, feuilles CSS, images ...) de votre site web (voir aussi Accélérateur web Varnish).
Sur un site web, les éléments statiques (pages HTML, feuilles de style, images ...) peuvent utiliser l'entête HTTP "Cache-Control" pour indiquer aux proxys que l'élément est "public" et peut être mis en cache. Dans une application PHP il suffit d'utiliser le code suivant:
$timeout = 3600 * 24; // 24h
header("Cache-Control: public,maxage=" . $timeout);
Malheureusement, la configuration par défaut de Varnish il est très prudente et met rarement les requêtes en cache, même si l'entête "Cache-Control" indique une contenu "public". Pour forcer Varnish a mettre ce contenu en cache, il faut modifier le fichier /etc/varnish/default.vcl comme suit:
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
# Si la requête est du type POST ou autre, passer au serveur sans chercher dans le cache
return (pass);
}
# Si on utilise l'authentification basique HTTP
if (req.http.Authorization) {
return (pass);
}
# Dans tous les autres cas (donc même si la requête comporte un cookie) envoyé par le client,
# chercher l'url dans le cache.
# Si le contenu est public, il se trouvera dans le cache
# Sinon, la requête sera transmise au serveur...
return (lookup);
}
# Lorsqu'on a reçu la réponse du serveur
sub vcl_fetch {
# Si le contenu n'est pas "public"
if (beresp.http.Cache-Control !~ "public" ||
# beresp.ttl <= 0s || peut poser problème avec le navigateur de Android
beresp.ttl <= 5s ||
beresp.http.Vary == "*") {
# Pendant 120s Varnish n'essaiera même pas de chercher dans son cache et enverra
# directement la requête au serveur
set beresp.ttl = 120 s;
return (hit_for_pass);
}
# Retirer les éventuels cookies envoyés par le serveur
# Si le site utilise les cookies (et sessions), le client recevra son cookie sur une autre page...
unset beresp.http.Set-Cookie;
# Stocker dans le cache, et envoyer au client
return (deliver);
}