Configuration et explication des subroutines de Varnish

Varnish Cache - Subroutines

Cet article fait suite à l’article sur la présentation de Varnish. Dans cette partie je vais détailler le fichier de base de configuration que j’ai mis en place. Il y a plein d’autres exemples sur le net qui traîne. Pour ma part je me suis basé sur une configuration déployé sur nos projets professionnels.

Le fichier est constitué de plusieurs subroutines (fonctions), ayant toutes un rôle différent.

Il y a plusieurs méthodes pour créer votre configuration :

  • Mettre toutes vos règles dans le même fichier à savoir le default.vcl
  • Créer un fichier différent par type de « règle », et pour améliorer la lisibilité de votre code. Soit chaque fichier contient :
    • les mêmes fonctions que le fichier default.vcl à savoir vcl_recv, ….
    • des nouvelles fonctions qui devront être appelé dans le fichier default.vcl via un call nom_de_fonction

De mon point de vue déclarer les mêmes fonctions dans différents fichier peut être source d’erreur.  La raison vient de la compilation du vcl (Merci à Guillaume Quintard pour les explications) :

  • varnish lit le vcl principal (default.vcl)
  • il inclut en place tous les fichiers spécifié par les « include « XXXX »; « , récursivement
  • il inclut le buitin.vcl tout à la fin de ce gros fichier
  • il va ensuite fusionner ensemble tous les vcl_recv, vcl_hash, vcl_hit, etc. en concaténant les différentes sections et en gardant leur ordre relatifs
  • puis traduction en C et compilation
De fait, s’il y a un return dans votre vcl principal ou dans un autre fichier, il se peut que du code défini dans un autre fichier de conf ou même du builtin.vcl ne soit jamais atteint et donc pris en compte. Idem il faut faire attention à l’odre d’inclusions des fichiers.
Je vais expliquer le fonctionnement et l’utilité des fonctions principales de Varnish que j’ai du modifier. Car le code de builtin.vcl contient déjà le grand nécessaire.
Pour certaines fonction je n’ai pas ajouté le code, il n’y a pas d’utilisé de surcharger celui de builtin.vcl.
Voici en image un récap des subroutines existantes
Varnish Cache - Subroutines

Subroutine vcl_init

Dans cette fonction il faut définir la variable vdir. Elle contiendra la liste des backends.

Subroutine vcl_recv

Cette fonction reçoit la requête envoyé par le client. Dans cette fonction on va définir si oui on non on va utiliser le fonctionnement de Varnish ou si on le bypass pour envoyé directement la requête au backend.
Contrairement à beaucoup d’exemple sur internet, je n’ai pas mis le bloc concernant le X-Forwarded-Fo r. En Varnish v4.1 ce code est totalement inutile et contre productif car il est déjà présent dans le code source de varnishd. Ce code est appelé avant le vcl_recv.
Pour que le backend puisse récupérer la véritable adresse IP du client il faut utiliser la variable $_SERVER['HTTP_X_FORWARDED_FOR']
On indique sur quel backend la requête devra être envoyé. Ceci est utile si en fonction du nom de domaine, vous souhaitez utiliser un backend différent.
On définit quelles sont les méthodes autorisées à être caché. Tout ne traffic POST ne doit bien évidement par être caché.
On nettoie les cookies inutiles.

La fonction se termine par un return car one ne veut pas utiliser le code du builtin.vcl. Car par défaut Varnish ne cache pas le contenu dès qu’un cookie est présent. Return a utiliser si vous êtes sure vouloir cacher vos pages même s’il a des cookies. Il est par contre possible de bypasser le cache en fonction de la présence de certains cookies (utile si vos utilisateurs sont connectés ou pour du debug), explication dans cet article Configuration avancé de Varnish :

 

Subroutine vcl_hash

Cette fonction permet de créer une clé d’identification de l’object (page) à mettre en cache. Par défaut la clé va être composé de l’url et du host ou du l’adresse IP.

Subroutine vcl_hit

Par défaut il n’est pas utile de modifier le code de cette fonction. Je rentrerai plus en détail sur cette fonction dans un autre article. Car elle permet d’utiliser le mode grace de Varnish.

Subroutines vcl_backend_response

Dans cette fonction on va analyser la réponse que le backend a envoyé à Varnish et ainsi étudier le code http de retour.

Dans le premier bloc, on va contrôler la taille du contenu de la page, et si elle est null, alors on va tenter de réinterroger le backend, et ceux 3 fois au maximun. Explication via un graphique du principe de retry.

Varnish Cache - Gestion du retry

On va également définir un ttl (durée de mise en cache dans Varnish) dans le cas où votre application web ne contient aucunes des informations suivantes dans le header. Ces informations sont lues par Varnish et l’informe de la durée pendant laquelle il doit conserver l’objet en cache avant de réinterroger le backend :

  • s-maxage dans le hedaer Cache-Control
  • max-age dans le hedaer Cache-Control
  • header Expires

Pour finir il y a toute une série de condition, qui indique qu’il ne faut pas mettre la page en cache. Notamment lorsqu’il y a un Set cookie, ou qu’il y a l’un des headers indique qu’il ne faut pas mettre en cache : (Surrogate-control: »no-store » ou que Cache-Control contienne soit no-cache soit no-store soit private)

Il y a un return en fin de fonction car il est inutile de prendre en compte le code de builtin.vcl

 

Subroutine vcl_deliver

Cette fonction est appelée avant que l’objet (page) soit délivré au client. C’est dans cette fonction qu’on peut rajouter des headers et du debug.

Subroutine vcl_backend_error

Cette fonction est appelée si le backend n’a pas pu retourner un résultat valide ou si le backend est down. Elle permet par d’exemple de changer le message d’erreur que l’utilisateur verra, en appelant la fonction synthetic.

Dans mon cas j’ai mis en place un système de retry, qui permet d’envoyer la même requête sur un autre backend ou de retenter sur le même. Dans la limite de 3 essaies maximun pour éviter une boucle infinie.

 

Vous avez un Varnish pleinement fonctionnel avec un système de retry en cas d’erreur.


Commenter

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *