22
0
Fork 0

Relecture/adaptation de la page HowtoVarnish.

This commit is contained in:
Romain Dessort 2016-11-02 11:05:25 -04:00
parent f0a656a83e
commit 4a0b59b705
1 changed files with 33 additions and 42 deletions

View File

@ -40,12 +40,12 @@ ExecStart=/usr/sbin/varnishd -a 0.0.0.0:80 -T localhost:6082 -f /etc/varnish/def
Détails de certaines options :
* `-a` : spécifie *IP*:*port* sur lequel Varnish écoute pour les requêtes HTTP. On peut ainsi spécifier une IP secondaire pour cœxister avec un autre service HTTP (Apache, Nginx) sur le port 80 (*-a 192.0.2.1:80*) ou faire écouter Varnish uniquement en local (*-a 127.0.0.1:8080*) ou alors le faire écouter de partout (*-a 0.0.0.0:80*) ou même spécifier plusieurs IP (*-a 0.0.0.0:80,127.0.0.1:81*)
* `-T` : spécifie l'interface d'admin web de Varnish
* `-a` : spécifie *IP*:*port* sur lequel Varnish écoute pour les requêtes HTTP. On peut ainsi spécifier une IP secondaire pour coexister avec un autre service HTTP (Apache, Nginx) sur le port 80 (*-a 192.0.2.1:80*) ou faire écouter Varnish uniquement en local (*-a 127.0.0.1:8080*) ou alors le faire écouter de partout (*-a 0.0.0.0:80*) ou même spécifier plusieurs IP (*-a 0.0.0.0:80,127.0.0.1:81*)
* `-T` : spécifie l'interface d'admin de Varnish, accessible avec `varnishadm`
* `-f` : spécifie le fichier des règles Varnish au format VCL (*Varnish Configuration Language*)
* `-s` : spécifie où est stocké le cache. Cela peut être en mémoire (*-s malloc,2G*) et/ou dans un fichier (*-s file,varnish_storage.bin,8G*)
Note 1 : le fichier */etc/default/varnish* [n'est malheureusement plus utilisé avec Systemd](https://bugs.debian.org/749272)
Note 1 : le fichier */etc/default/varnish* [n'est malheureusement plus utilisé avec Systemd](https://bugs.debian.org/749272). Cependant il reste toujours utilisé par `/etc/init.d/varnish reload` qui ne fait pas appel à systemd !
Note 2 : avant Debian 8, [Varnish ne supportait pas d'être lancé avec *umask 077*, c'est corrigé en Debian Jessie](https://bugs.debian.org/696504)
@ -94,8 +94,8 @@ Il est aussi possible d'écrire ces logs dans des fichiers en lançant varnishlo
La syntaxe VCL est complexe mais puissante. On découpe un fichier VCL en plusieurs sous-routines dans lesquelles on définit des actions/comportements en fonction de certaines conditions. Les sous-routines principales sont *vcl_recv* et *vcl_backend_response* :
* **vcl_recv** est appelé AVANT le début de la requête au backend. On peut donc choisir vers quel backend renvoyer la requête. On peut aussi de modifier la requête (modifier des entêtes HTTP, supprimer des demandes de cookies, etc.). Seul les actions `set req.` sont possibles.
* **vcl_backend_response** (remplace **vcl_fetch** depuis Varnish 4) est appelé APRÈS la réception de la réponse du backend. Les actions `set req.` sont possibles, mais aussi `set beresp.` (pour *backend response*).
* **vcl_recv** est appelé AVANT le début de la requête au backend. On peut donc choisir vers quel backend renvoyer la requête. On peut aussi modifier la requête (modifier des entêtes HTTP, supprimer des demandes de cookies, etc.). Seul les actions `set req.` sont possibles.
* **vcl_backend_response** (remplace **vcl_fetch** depuis Varnish 4) est appelé APRÈS la réception de la réponse du backend. Les actions `set bereq.` (équivalentes à `set req.` dans *vcl_recv*) sont possibles, mais aussi `set beresp.` (pour *backend response*).
Attention, Varnish charge [ses propres sous-routines par défaut](#configuration-par-défaut) et si on veut changer son comportement il est impératif de copier la sous-routine par défaut (voir [#configuration-par-défaut]()) puis de la modifier !
@ -274,22 +274,22 @@ Voici un certain nombre de conditions possibles :
# Condition sur l'entête HTTP Host:
if (req.http.host ~ "^regex$")
# Présence d'un cookie
if (req.http.cookie) {
if (req.http.cookie)
# Condition sur l'URL demandée
if (req.url ~ "^/regex$")
# Si le backend est accessible
if (req.backend.healthy)
# Présence entête Accept-Encoding
# Présence de l'entête Accept-Encoding
if (req.http.Accept-Encoding)
# Condition sur la requête faite
if (req.request != "GET" && req.request != "HEAD")
if (req.method != "GET" && req.method != "HEAD")
# Présence de l'entête X-Forwarded-For
if (req.http.x-forwarded-for)
# Condition sur les entêtes envoyés
if (req.http.Authorization || req.http.Cookie)
# Condition
# Condition sur la politique de mise en cache
if (req.http.Cache-Control ~ "no-cache")
# Condition sur le temps de mise (Cache-Control: max-age a priori)
# Condition sur le temps de mise en cache (Cache-Control: max-age a priori)
if (beresp.ttl < 120s)
# Condition sur le statut des réponses
if (obj.status == 404 || obj.status == 503 || obj.status == 500)
@ -302,10 +302,9 @@ Voici un certain nombre d'actions possibles :
set req.backend_hint = baz;
# Supprimer les cookies dans la requête
unset req.http.cookie;
remove req.http.cookie;
# Supprimer un certain nombre d'entêtes HTTP
remove req.http.X-Forwarded-For;
remove req.http.Accept-Encoding;
unset req.http.X-Forwarded-For;
unset req.http.Accept-Encoding;
# Positionner un certain nombre d'entêtes HTTP pour la requête
set req.http.X-Forwarded-For = client.ip;
set req.http.Accept-Encoding = "gzip";
@ -314,7 +313,7 @@ set req.http.Accept-Encoding = "deflate";
set obj.http.expires = "Mon, 1 Jan 2007 00:00:01 GMT";
set obj.http.X-foo = "bar";
# Renvoyer une erreur HTTP
error 404 "Page not found";
return(synth(404, "Page not found"));
~~~
Enfin, voici les principaux [comportements possibles](https://www.varnish-cache.org/docs/4.0/users-guide/vcl-built-in-subs.html) :
@ -333,7 +332,7 @@ return (restart);
## Gestion du cache
Par défaut Varnish respecte le comportement standard d'un reverse-proxy : pas de cache en présence de cookie, respect des entêtes HTTP envoyés par le client et backend : sa configuration par défaut devrait convenir pour les sites codés correctement ! L'avantage est que l'on peut facilement intervenir sur ce comportement standard pour ajouter des exceptions.. si le code d'un site est incorrect.
Par défaut Varnish respecte le comportement standard d'un reverse-proxy : pas de cache en présence de cookie, respect des entêtes HTTP envoyés par le client et backend : sa configuration par défaut devrait convenir pour les sites codés correctement ! L'avantage est que l'on peut facilement intervenir sur ce comportement standard pour ajouter des exceptions... si le code d'un site est incorrect.
Le temps de mise en cache par défaut peut être défini avec l'option `-t` à [#varnishd](). Par défaut il est à 120 secondes. On peut le changer avec `set beresp.ttl` :
@ -345,7 +344,7 @@ sub vcl_backend_response {
}
~~~
Grâce aux règles VCL on peut vraiment définir finement la mise en cache ou pas, en complément des entêtes de cache renvoyés par le code. On peut ainsi mettre en cache même si certains cookies sont présents.
Grâce aux règles VCL on peut vraiment définir finement la mise en cache ou pas, en complément des entêtes de cache renvoyés par le code. On peut ainsi mettre en cache même si certains cookies sont présents, en les supprimant de la requête.
~~~
sub vcl_recv {
@ -397,6 +396,12 @@ On peut purger le cache en ligne de commande.
Purge en une seule ligne :
~~~
# varnishadm 'ban req.url ~ .'
~~~
Ou si le port et/ou le chemin vers le secret n'est pas celui par défaut :
~~~
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 'ban req.url ~ .'
~~~
@ -404,7 +409,7 @@ Purge en une seule ligne :
Il est recommandé d'utiliser le CLI Varnish (on obtiendra ainsi un code de retour *200*) :
~~~
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
# varnishadm
varnish> ban req.url ~ ".png$"
200
@ -432,25 +437,12 @@ acl local {
sub vcl_recv {
# placer cette directive en premier, sinon une autre risque de matcher avant et la purge ne sera jamais effectuée
if (req.request == "PURGE") {
if (req.method == "PURGE") {
if (client.ip ~ local) {
return(lookup);
return(purge);
}
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
~~~
### Taille du cache
@ -579,8 +571,8 @@ sub vcl_recv {
set req.backend = default;
# Compatiblity with Apache log
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
unset req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Normalize Content-Encoding
if (req.http.Accept-Encoding) {
@ -604,7 +596,7 @@ sub vcl_recv {
if (req.http.cookie) {
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
if (req.http.cookie ~ "^ *$") {
remove req.http.cookie;
unset req.http.cookie;
}
}
@ -654,14 +646,14 @@ sub vcl_backend_response {
~~~
sub vcl_recv {
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
unset req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Normalize Content-Encoding
if (req.http.Accept-Encoding) {
# Compress a compressed format is silly
if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|lzma|tbz|zip|rar)(\?.*|)$") {
remove req.http.Accept-Encoding;
unset req.http.Accept-Encoding;
}
# use gzip when possible, otherwise use deflate
if (req.http.Accept-Encoding ~ "gzip") {
@ -677,7 +669,7 @@ sub vcl_recv {
if (req.http.cookie) {
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
if (req.http.cookie ~ "^ *$") {
remove req.http.cookie;
unset req.http.cookie;
}
}
@ -714,9 +706,8 @@ sub vcl_backend_response {
sub vcl_deliver {
if (obj.hits > 0) {
if (resp.http.X-Varnish ~ "[0-9]+ +[0-9]+") {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
@ -731,7 +722,7 @@ La taille maximum d'un objet en cache ne semble limitée que par la taille du ca
### Comment prendre en compte un changement de configuration / règles ?
Un reload ne suffit parfois pas, un restart sera nécessaire dans certains cas. De plus, il faut vider du cache les éventuels objects concernés.
Un reload ne suffit parfois pas, un restart sera nécessaire dans certains cas. De plus, il faut vider du cache les éventuels objets concernés.
### Temps d'attente du client HTTP ?