Comment utiliser concrètement le cache Varnish ?
Setup simple de Varnish 4
Pour l’installation de Varnish 4 sur debian et son utilisation sur le framework Symfony 3 :
- Installer Varnish
2. Configurer le fichier de configuration par défaut de varnish (ex sur debian: /etc/varnish/default.vcl) pour ajouter votre serveur web/.
- Exemple :
backend default {
.host = "127.0.0.1";
.port = "8080";
}
- Le host étant l’ip ou le nom d’hôte pointant sur une ip unique. Ce paramètre est obligatoire.
- Le port sur le serveur web qui écoute les requêtes entrantes
3. Configurer votre serveur web afin qu’il écoute sur le port spécifié dans le fichier de configuration varnish et s’assurer qu’il est différent de celui de Varnish.
Petit rappel : n’oubliez pas que varnish est un serveur de cache et que c’est donc lui qui doit recevoir vos requêtes (il fait office de Proxy) ! Il faut qu’il écoute votre port 80 (ou 443 pour l’HTTPS) et que votre serveur HTTP soit sur un autre port (par exemple 8080) ou IP et soit appelé exclusivement par Varnish.
Ensuite, pour permettre à Varnish de prendre en charge les balises ESI, il faut modifier le fichier /etc/varnish/default.vcl comme indiqué ci-dessous :
//On défini ici l’adresse de notre serveur HTTP
backend default {
.host = "127.0.0.1";
.port = "8080";
}
//Puis dans ce block qui est appelé après la réception d’une requête
//nous définissons l’usage des ESI dans les headers
sub vcl_recv {
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
//Ensuite, ce block est appelé après la réception des headers de réponse.
//Nous supprimons le header et activons les ESI
sub vcl_backend_response {
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
Enfin redémarrer le service Varnish pour prendre en compte les modifications :
sudo service varnish restart
Une fois cette configuration mise en place, il faut activer la gestion des ESI dans Symfony, aller dans ‘app/config/config.yml’ et ajoutez la ligne suivante dans “framework”:
framework:
esi: { enabled: true }
Pensez bien à vider le cache.
Attention, dans l’état actuel, même votre nom de domaine avec app_dev.php est caché par Varnish. Si vous souhaitez ne pas cacher, il faut ajouter dans /etc/varnish/default.tcl :
sub vcl_backend_response {
// Check for ESI acknowledgement and remove Surrogate-Control header
….
// Check if force no cache on app_dev.php
if (bereq.url ~ "app_dev.php") {
set beresp.uncacheable = true;
set beresp.ttl = 0s; # how long not to cache this url.
}
}
Autre solution, que je trouve moins propre, définir vos temps d’expiration dans le config.yml et surcharger le tout dans le config_dev.yml.
Et… C’est tout ! Vous pouvez maintenant utiliser les balises ESI dans vos vues twig :-)
Exemple d’utilisation sur Symfony 3
Pour commencer, on ajoute l’action par défaut (qui va être exécutée lors d’une requête sur /) dans notre controller, qui va garder la page en cache pendant 10 secondes :
public function indexAction(Request $request)
{
$response = $this->render(
'default/index.html.twig',
[
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..'),
]
);
$response->setSharedMaxAge(10);
return $response;
}
}
Puis on définit la vue associée :
index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrapper">
<div id="container">
<div class="col2">
<h2>Render controller without ESI</h2>
{{ render(controller('AppBundle:Default:esi')) }}
<div>
<div class="clear"></div>
</div>
</div>
{% endblock %}
On remarquera dans la vue précédente, l’appel d’un render classique, qui est là pour afficher l’heure actuelle.
public function esiAction(Request $request)
{
$response = $this->render('default/esi.html.twig');
$response->setSharedMaxAge(5);return $response;
}Esi.html.twig<div style="border: solid 1px black;">
<div>{{'now'|date('d/m/Y H:i:s')}}</div>
</div>
On obtient donc ce rendu :
Le but maintenant, c’est de voir la différence avec un render qui va faire générer une balise HTML <esi /> :
[...]
<div class="col2">
<h2>Render controller without ESI</h2>
{{ render(controller('AppBundle:Default:esi')) }}
<div>
<div class="col2">
<h2>Render controller with ESI</h2>
{{ render_esi(controller('AppBundle:Default:esi')) }}
</div>
[...]
N.B. : Dans le render_esi il est possible aussi de définir une route, et non un controller.
{{ render_esi(path(“the_big_name”, {}) }}
Et définir donc votre route the_big_name dans votre routing.
On recharge notre page…
C’est identique, normal, c’est notre premier chargement.
On recharge de nouveau au bout de 5 secondes… Et là, magie, la date a changé à droite mais pas à gauche, pourtant ça appelle la même action et la même vue !
Bien évidemment il ne s’agit pas de magie. Vous remarquerez que dans l’action esiAction nous avons défini dans la réponse unsetSharedMaxAge à 5 secondes. Dans votre vue twig, la fonction render ne prendra pas en compte cette fonction, elle ne fait que prendre le HTML que retourne l’action sans s’occuper des en-têtes de réponse.
<div style="border: solid 1px black;">
<div>22/04/2016 17:47:24</div>
</div>
Par contre render_esi, lui va créer une URI pour ensuite l’inclure dans une balise <esi:include />
<esi:include src="/_fragment?_path=_format%3Dhtml%26_locale%3Den%26_controller%3DAppBundle%253ADefault%253Aesi&_hash=WOH3ovJMaB%2FBojX0G%2FUK1dQEvj%2B3mtynS9CL8fEJ98I%3D" />
Et comme c’est une URI, alors elle a sa propre réponse, donc ses propres en-têtes et pour finir son propre temps d’expiration.
Pour aller plus loin
Vous pouvez également retrouver nos autres articles sur le sujet :
Comment monitorer votre instance Varnish ?
Comment configurer le comportement du cache Varnish ?
Comment fonctionne le cache Varnish ?
Nous publions régulièrement des articles sur des sujets de développement produit web et mobile, data et analytics, sécurité, cloud, hyperautomatisation et digital workplace.
Suivez-nous pour être notifié des prochains articles et réaliser votre veille professionnelle.
Retrouvez aussi nos publications et notre actualité via notre newsletter, ainsi que nos différents réseaux sociaux : LinkedIn, Twitter, Youtube, Twitch et Instagram
Vous souhaitez en savoir plus ? Consultez notre site web et nos offres d’emploi.