Sep 262013
 

Pour modifier le ttl avec un ratio, il faut ajouter un bout de C :
Au début de la configuration :

C{
        #include <string.h>
        #include <stdlib.h>
        void TIM_format(double t, char *p);
        double TIM_real(void);
}C

Dans le vcl_fetch :

if (beresp.ttl > 0s ) {
        C{
                double obj_ttl = VRT_r_beresp_ttl(sp);
                double ratio = 0.9;
                double new_ttl = obj_ttl*ratio;
                VRT_l_beresp_ttl(sp, new_ttl);
        }C
}

Pour vérifier, vous pouvez ajouter la ligne suivante à la fin du vcl_fetch :

set beresp.http.X-Varnish-TTL = beresp.ttl;
Fév 072013
 

L’ESI (Edge Side Includes) est supporté par Varnish. C’est un language de balisage HTML permettant d’assembler une page dynamique.
Cela permet de cacher avec différents temps en cache ou de ne pas cacher, différents bloc d’une page.
Par exemple :
ESI
On peut définir le temps de cache avec le header « Cache-Control : max-age » ou directement dans la configuration varnish.
Voici une page d’exemple :
– index.php :

<?php
        header('Cache-Control: max-age=3600');
?>
<title>Page de test ESI</title>
<html><body>
        Cette page est cach&eacute;e pourtant j'arrive &agrave; afficher l'heure :
        <esi:include src="/dyn/date.php"/>
</body></html>

– date.php :

<?php
        header('Cache-Control: max-age=0');
        echo date('Y-m-d H:i:s');
?>

Il faut activer l’ESI dans la configuration varnish :

sub vcl_fetch {
        set beresp.do_esi = true;

Si vous avez un panier, il faut pouvoir identifier les utilisateurs avec une session php.
Si il y a une session php, elle ne peut pas être définit par la page cachée : il faudra donc la générer autrement :

<script type='text/javascript' src="/dyn/sessions.php"></script>

– sessions.php :

<?php
        session_start();
?>

Pour que tous les utilisateurs reçoivent la page commune cachée et qu’elle reste dynamique en fonction des utilisateurs il faut enlever la session des cookies pour les pages/parties communes et la laisser pour les pages/parties individuelles.
Dans la configuration varnish :

if ( ! req.url ~ "^/dyn" ) {
        set req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", "");
        if (req.http.Cookie ~ "^$") {
            unset req.http.Cookie;
        }

On peut tester avec cette page :
– index.php :

<?php
        header('Cache-Control: max-age=3600');
?>
<title>Page de test ESI</title>
<html><body>
        Cette page est cach&eacute;e pourtant j'arrive &agrave; afficher l'heure :
        <esi:include src="/dyn/date.php"/>
        <br>Ainsi que l'ID de session : <esi:include src="/dyn/phpsess.php"/>
        <script type='text/javascript' src="/dyn/sessions.php"></script>
</body></html>

– phpsess.php :

<?php
        header('Cache-Control: max-age=0');
        echo $_COOKIE["PHPSESSID"];
?>

Le résultat : http://blog.jeremm.fr/esi/
A la première visite vous n’avez pas de session, elle ne sera donc pas affichée.

Jan 132013
 

Si vos sites ne sont pas parcourus régulièrement, les pages ne seront plus dans votre cache varnish, vous pourriez augmenter le ttl de vos pages mais si vous mettez à jour régulièrement vos sites cela peut être embêtant.
La solution, créer un cron qui parcours votre site avec ce script :

#!/bin/bash
 
Sitemap='www.exemple.com/sitemap.xml'
Site='www.exemple.com'
wget='/usr/bin/wget'
grep='/bin/grep'
awk='/usr/bin/awk'
find='/usr/bin/find'
mount='/bin/mount'
umount='/bin/umount'
sed='/bin/sed'
wc='/usr/bin/wc'
cut='/usr/bin/cut'
 
if [ `$mount -l | $grep /tmp/wget | $wc -l` -gt 0 ] ; then exit 1 ; fi
 
touch /tmp/cookies.txt
$wget -q -O /dev/null "URL pour régénérer le sitemap"
 
if [ ! -d /tmp/wget ] ; then
   mkdir /tmp/wget
fi
 
$mount -t tmpfs -o size=25M tmpfs /tmp/wget
cd /tmp/wget
 
for site in $Sitemap ; do
   for url in `$wget -q -O - "http://$site" | $grep '<loc>'  | $awk -F'<loc>' '{print $2}' | $awk -F'</loc>' '{print $1}'` ; do
      $wget -q -p --save-cookies /tmp/cookies.txt --load-cookies /tmp/cookies.txt "$url"
      for index in `$find . -type f | $sed 's:^./::' | $grep index.html` ; do
            for href in `$grep href "$index" | $cut -d"'" -f2 | $cut -d'"' -f2 | $grep http | $grep "$Site"` ; do
                  $wget -q -p --save-cookies /tmp/cookies.txt --load-cookies /tmp/cookies.txt --header='Accept-Encoding: gzip, deflate' "$href"
                  $wget -q -p --header='Accept-Encoding: gzip, deflate' "$href"
            done
      done
      for file in `$find . -type f | $sed 's:^./::' | $grep -v index.html` ; do
          $wget -q -O /dev/null  --save-cookies /tmp/cookies.txt --load-cookies /tmp/cookies.txt --header='Accept-Encoding: gzip, deflate' "http://$file"
          $wget -q -O /dev/null  --header='Accept-Encoding: gzip, deflate' "http://$file"
      done
      for file in `$find . -type f | $sed 's:^./::' | $grep index.html | $sed 's:index.html::'` ; do
          $wget -q -O /dev/null  --save-cookies /tmp/cookies.txt --load-cookies /tmp/cookies.txt --header='Accept-Encoding: gzip, deflate' "http://$file"
          $wget -q -O /dev/null  --header='Accept-Encoding: gzip, deflate' "http://$file"
      done
      rm -rf /tmp/wget/*
   done
done
rm /tmp/cookies.txt
cd /tmp/ ; $umount /tmp/wget ; rm -rf /tmp/wget

Maj 13/01/12 : Ajout href

Mar 052012
 

Avec varnish, par défaut quand vous appelez la routine pass,

return(pass);

votre requête sera envoyée directement au backend sans vérifier le cache mais si la réponse est « cachable » http://blog.jeremm.fr/?p=190, Varnish la sauvegardera dans son cache.

Bien sûr cela ne sert souvent à rien car la prochaine requête passera encore par le routine pass, et l’objet dans le cache ne sera pas utilisée.
Mais avec une configuration plus complexe, l’objet en cache pourrait être utilisé.

Pour être sûr que les objets passant par la routine pass ne soit pas cachée, ajoutez :

sub vcl_pass {
        set req.http.X-marker = "pass" ;
}

et dans le vcl_fetch :

if (req.http.X-marker == "pass" ) {
        unset req.http.X-marker;
        set beresp.ttl = 0s ;
}
Mar 052012
 

Pour savoir comment Varnish décide si un objet peut être caché :

Varnish regarde deux paramètres dans l’en-tête HTTP que lui renvoie le backend.

  • La date du paramètre Expires :
  1. Si il est dans le passé, il ne cache pas
  2. Si il est dans le futur, il cachera jusqu’à la date.
  • La valeur du s-maxage ou max-age du paramètre Cache-Control :
  1. Si il est égal à 0, il ne cachera pas
  2. Si il est supérieur à 0, il cachera le nombre de seconde que ce paramètre lui dit (avec ce paramètre, Varnish ne regardera pas le paramètre Expires)

Si aucun des deux paramètres n’est présent, Varnish cachera l’objet avec le temps de rafraichissement par défaut.

Vous pouvez bien sûr ajouter des règles pour forcer ou non des objets dans le cache.