WEB-d Développement Web

PHP, SQL, HTML5, CSS3, Javascript, Mootools, Référencement, SEO, CMS, e-commerce, Apache, Linux, Ubuntu, ...

Varnish : mettre en cache tout le contenu public

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).

Varnish Cache

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);
}

Articles similaires