evoformations/support/varnish.tex

304 lines
11 KiB
TeX
Raw Normal View History

% Copyright (c) 2004-2010 Evolix <info@evolix.fr>
% Permission is granted to copy, distribute and/or modify this document
% under the terms of the GNU Free Documentation License, Version 1.2
% or any later version published by the Free Software Foundation;
% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
% A copy of the license is included at http://www.gcolpart.com/howto/fdl.html
\chapter{Varnish}
Site officiel: \url{https://www.varnish-cache.org/}
\section{Pr<EFBFBD>sentation}
Varnish est un reverse proxy HTTP dans le but premier est la mise en cache de
contenu. Il est <20>galement capable de g<>rer plusieurs backend, avec
r<EFBFBD>partition de charge et d<>tection de panne.
Varnish, d<>velopp<70> en C, se concentre principalement sur la performance sur des infrastructures
<EFBFBD> haut et tr<74>s haut trafic.
Un autre point fort est son langage de configuration, qui permet de param<61>trer
finement le comportement de Varnish aux diff<66>rentes <20>tapes du traitement de la
requ<EFBFBD>te.
Le d<>veloppement de Varnish a commenc<6E> en 2005, et il est distribu<62> sous licence
BSD.
\section{Installation}
Varnish est disponible dans les d<>p<EFBFBD>ts de Debian Squeeze en version 2.1.3. Il
existe <20>galement un backport du paquet de Wheezy, qui fournit la version 3.0.2.
Cette version apporte de nombreuses am<61>lioration et fonctionnalit<69> dans la
gestion du load-balancing entre les backends.
Installation du paquet:
\begin{verbatim}
# aptitude install varnish
\end{verbatim}
\section{Configuration}
Les possibilit<69>s offertes pour la configuration de Varnish sont assez vastes,
elles seront abord<72>s par grands th<74>mes.
\subsection{Param<EFBFBD>trage de base}
Tout d'abord, il est n<>cessaire de renseigner quelques informations de base au
d<EFBFBD>mon \texttt{varnishd}. Cette configuration se passe dans le fichier
\texttt{/etc/default/varnish}. Plusieurs cas de figure sont propos<6F>s <20> titre
d'exemple dans ce fichier, en voici un autre avec quelques optimisations
suppl<EFBFBD>mentaires:
\begin{verbatim}
DAEMON_OPTS="-a 192.0.2.1:80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,3G
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,10G
-p thread_pools=<Number of CPU cores>
-p thread_pool_add_delay=2
-p thread_pool_max=5000"
umask 022
\end{verbatim}
Et voici quelques explications sur les param<61>tres:
\begin{description}
\item[\texttt{-a 192.0.2.1:80}] \hfill \\
Il s'agit du couple IP,port sur lequel Varnish attendra les requ<71>tes HTTP <20>
traiter.
\item[\texttt{-T localhost:6082}] \hfill \\
Il s'agit du couple IP,port sur lequel sera accessible l'interface
d'administration de Varnish (trait<69> plus loin dans ce chapitre).
\item[\texttt{-f /etc/varnish/default.vcl}] \hfill \\
Cette option indique le fichier de configuration <20> utiliser.
\item[\texttt{-S /etc/varnish/secret}] \hfill \\
\item[\texttt{-s malloc,3G}]
\item[\texttt{-s file,/var/lib/varnish/\$INSTANCE/varnish\_storage.bin,10G}] \hfill \\
On indique ici qu'une partie du cache sera stock<63> en m<>moire 3~Go, ainsi que
dans un fichier plat sur le disque, qui sera limit<69> <20> 10~Go.
\item[\texttt{-p thread\_pools=<Number of CPU cores>}]
2012-05-22 03:42:54 +02:00
\item[\texttt{-p thread\_pool\_add\_delay=2}]
\item[\texttt{-p thread\_pool\_max=5000}] \hfill \\
L'option \texttt{-p} permet de modifier diff<66>rents param<61>tres d'ex<65>cution.
De nombreux param<61>tres peuvent <20>tre modifi<66>s, la liste compl<70>te avec leur
description se trouve ici:
\url{https://www.varnish-cache.org/docs/2.1/reference/varnishd.html}.
2012-05-22 03:42:54 +02:00
\texttt{thread\_pools} indique le nombre de groupe de threads <20> lancer. Cette
valeur ne devrait pas d<>passer le nombre de c\oe{}ur disponible sur le syst<73>me
(pour des raisons de performance). Pour \texttt{threa\_poo\_ad\_delay}, il
s'agit du temps en milisecondes <20> attendre avant la cr<63>ation d'un nouveau
thread. Et enfin \texttt{threa\_poo\_max} repr<70>sente le nombre total de
thread maximum <20> ne pas d<>passer, tout pool confondus.
\item[\texttt{umask 022}] \hfill \\
Varnish s'attend <20> avoir un umask <20> 022 pour s'ex<65>cuter
correctement. \'Etant donn<6E> qu'il n'est pas forc<72> dans le script d'init,
nous le pla<6C>ons ici manuellement.
\end{description}
\subsection{Aper<EFBFBD>u de la syntaxe du langage VCL}
\subsection{Gestion du cache}
En se positionnant entre le client et le serveur applicatif, Varnish permet de
lire et surcharger si besoin les ent<6E>tes HTTP de contr<74>le du cache. Par d<>faut,
celle ci sont lues et pris en compte, mais on peut red<65>finir le comportement
dans la configuration.
Voici quelques exemples d'utilisation typique:
\paragraph{Forcer le TTL pour certains contenu}
\begin{verbatim}
sub vcl_fetch {
if (req.url ~ "\.(png|gif|jpg)$") {
set beresp.ttl = 5d;
set beresp.http.magicmarker = "1";
}
}
sub vcl_deliver {
if (resp.http.magicmarker) {
unset resp.http.magicmarker;
set resp.http.Age = "0";
}
}
\end{verbatim}
\texttt{beresp.http.magicmarker} permet de marquer l'objet pour pouvoir ensuite
remettre son age <20> 0 (dans \texttt{vcl\_deliver}.
Pour que le changement de TTL le soit <20>galement cot<6F> client, on r<><72>crit le
header HTTP \emph{Cache-Control} en ajoutant (dans le premier \texttt{if}:
\begin{verbatim}
set beresp.http.cache-control = ``max-age=432000'';
\end{verbatim}
\paragraph{Indiquer si un objet provient du cache ou pas dans les headers HTTP}
Dans un but de debugage, il peut <20>tre int<6E>ressant d'indiquer si un contenu
provient du cache de Varnish ou non. Cela se fait simplement comme ceci:
\begin{verbatim}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
\end{verbatim}
\subsection{Gestion du load-balancing}
Tout d'abord, il faut d<>finir au moins un backend pour que l'ensemble puisse
fonctionner correctement. Cela se fait <20> l'aide de la directive
\texttt{backend}, comme ceci:
\begin{verbatim}
backend www00 {
.host = "192.0.2.8";
.port = "80";
}
backend www01 {
.host = "192.0.2.14";
.port = "80";
}
\end{verbatim}
Il est ensuite possible de grouper ces backends dans un cluster, appel<65>
\emph{director} dans le langage de Varnish:
\begin{verbatim}
director baz round-robin {
{ .backend = www00; }
{ .backend = www01; }
}
\end{verbatim}
Et enfin, on indique dans quel cas il sera utilis<69> (dans l'exemple il sera
utilis<EFBFBD> dans tous les cas, pas de condition):
\begin{verbatim}
sub vcl_recv {
set req.backend = baz;
}
\end{verbatim}
Il s'agit ici de la configuration la plus simple possible. Maintenant, il peut
<EFBFBD>tre int<6E>ressant d'ajuster certains param<61>tres:
\begin{itemize}
\item Dans l'exemple ci dessus, le director est en mode round-robin. Le trafic
est alors r<>parti <20>quitablement entre les backend. On peut d<>finir un
<20>poids<64> pour chacun des backends, afin de jouer sur la r<>partition du trafic
entre eux:
\begin{verbatim}
director baz random {
{
.backend = www00;
.weight = 6;
}
{
.backend = www01;
.weight = 4;
}
}
\end{verbatim}
Pour cela, on change le mode du director pour \emph{random}.
\item Une directive importante est \texttt{.max\_connections}. Elle permet de
limiter le nombre de connexions concurrentes envoy<6F>es sur un backend. En en
positionnant une sur chacun des backends, Varnish saura qu'il devra ignorer
le backend satur<75> et en choisir un autre, afin de ne pas le surcharg<72>.
\begin{verbatim}
backend www00 {
.host = "192.0.2.8";
.port = "80";
.max_connections = 80;
}
\end{verbatim}
\item Il est possible <20>galement de r<>partir les requ<71>tes sur les backends
suivant des crit<69>res sur la requ<71>te. Le mode du director <20> utiliser est
alors \emph{client}:
\begin{verbatim}
director baz client {
{ .backend = www00; }
{ .backend = www01; }
}
sub vcl_recv {
set req.backend = baz;
set client.identity = req.ip;
}
\end{verbatim}
Dans l'exemple ci-dessus, le crit<69>re utilis<69> est l'IP du client
(\texttt{client.identity = req.ip}. Les autres crit<69>res possibles sont le
user-agent (\texttt{req.http.user-agent}), l'URL (\texttt{client.url}) ou encore
un cookie de session (\texttt{req.http.cookie}).
\end{itemize}
\subsection{Gestion du failover}
Nous avons vu que Varnish <20>tait capable de g<>rer plusieurs backend en contr<74>lant
la r<>partition des requ<71>tes sur chacun d'eux. Il est aussi capable de d<>tecter
une panne sur un backend, et de prendre en compte cet <20>v<EFBFBD>nement pour modifier
son comportement: utiliser un autre backend, ou renvoyer ces fichiers en cache.
\subsubsection{D<EFBFBD>tection lors de la requ<71>te}
Il est possible d'ajuster diff<66>rent param<61>tres indiquant le temps d'attente
maximum tol<6F>r<EFBFBD> par Varnish lors de l'interrogation d'un backend:
\begin{verbatim}
backend www00 {
.host = "192.0.2.6";
.port = "80";
.connect_timeout = 1s;
.first_byte_timeout = 3s;
.between_bytes_timeout = 2s;
}
\end{verbatim}
Les directives sont assez explicites. Pass<73> ce d<>lai, Varnish ira interroger le
backend suivant.
\subsubsection{Surveillance p<>riodique des backends}
La m<>thode pr<70>c<EFBFBD>dente est essentielle, mais pas suffisante en elle-m<>me; en
effet, m<>me si Varnish basculera sur un autre backend en cas de saturation du
premier, le traitement de la requ<71>te sera ralenti par l'expiration des d<>lais
d'attente. D'autre part, une erreur HTTP 5xx par exemple sur un backend
n'emp<6D>chera pas Varnish de continuer <20> lui envoyer des requ<71>tes.
Varnish offre la possibilit<69> de surveiller r<>guli<6C>rement ses backends et les
marquer <20>ventuellement comme <20>down<77>. Pour cela, il est n<>cessaire de lui
indiquer comment les surveiller, avec la directive
\texttt{.probe}:
\begin{verbatim}
backend www00 {
.host = "192.0.2.6";
.port = "80";
.probe = {
.request = "GET / HTTP/1.1"
"Host: www.example.com"
"User-Agent: test Varnish"
"Connection: close"
"Accept-Encoding: text/html" ;
.timeout = 1s;
.interval = 5s;
.window = 8;
.threshold = 6;
}
}
\end{verbatim}
On d<>finit la requ<71>te HTTP que Varnish devra envoyer au backend, ainsi que
diverses directives. Le backend devra obligatoirement retourn<72> un code HTTP 200,
il sera consid<69>r<EFBFBD> comme <20>down<77> si ce n'est pas le cas.
Dans l'exemple ci-dessus, les checks sont fait sur un intervalle de 5 secondes,
et s'attend <20> avoir une r<>ponse en moins d'une seconde. Les directives
\texttt{.window} et \texttt{.threshold} permet de d<>finir un cycle d'hyst<73>r<EFBFBD>sis:
pour que le backend soit vu comme <20>tant <20>down<77>, il faut que, sur une quantit<69> de
8, 6 checks ont <20>chou<6F>. Et inversement, pour qu'il repasse <20>up<75>, il faut que 6
checks sur les 8 ont r<>ussi.
\subsubsection{Saint mode}
\section{Administration}
\section{Gestion des logs}