Varnish, booster Apache sur votre VPS

Varnish est un serveur de cache HTTP qui va fonctionner comme reverse proxy pour le serveur. Il vas permettre d’accélérer le chargement des sites web en prennent en charge les requêtes HTTP et en les transférant à Apache uniquement si les pages demandées ne sont pas déjà en cache.

Installation de Varnish

Afin de disposer de la dernière version de Varnish on ajoute son dépôt avant de l’installer.

$ apt-get install apt-transport-https 
$ curl https://repo.varnish-cache.org/ubuntu/GPG-key.txt | apt-key add -
$ echo "deb https://repo.varnish-cache.org/ubuntu/ trusty varnish-4.0" >> /etc/apt/sources.list.d/varnish-cache.list
$ apt-get update
$ apt-get install varnish

Configuration de Varnish

La configuration de Varnish se fait par l’intermédiaire de deux fichiers. Le premier est /etc/default/varnish que l’on vas modifier en remplaçant le port 6081 par le port 80.

DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

En faisant cette modification, on s’assure que Varnish sera en écoute sur le port 80 et traitera donc toutes les requêtes HTTP.

Le second fichier à éditer est /etc/varnish/default.vcl. Nous allons le modifier en nous appuyant sur les recommandations que l’on trouve sur le site de Varnish : Step-by-step: Speed Up WordPress with Varnish Software. La configuration sera donc la suivante :

vcl 4.0;

# Nous définissons ici l'adresse est le port du serveur de backend vers lequel seront routées
# les requêtes. Dans notre cas, Apache tournera en local est sera en écoute sur le port 8080
backend default {
    .host = "127.0.0.1";
    .port = "8080";  
}

acl purge {
  "localhost";
  "<server ip address or hostname>";  # à remplacer par l'adresse de votre serveur
}

sub vcl_recv {
    # Happens before we check if we have this in cache already.
    #
    # Typically you clean up the request here, removing cookies you don't need,
    # rewriting the request, etc.
  if (req.method == "PURGE") {
    if (client.ip !~ purge) {
      return (synth(405));
    }
    if (req.http.X-Purge-Method == "regex") {
      ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
      return (synth(200, "Banned."));
    } else {
      return (purge);
    }
  }

  # Configuration spécifique à WordPress
  # On ne met pas en cache l'admin et la page de login
  if (req.url ~ "wp-admin|wp-login") {
    return (pass);
  }
  set req.http.cookie = regsuball(req.http.cookie, "wp-settings-\d+=[^;]+(; )?", "");
  set req.http.cookie = regsuball(req.http.cookie, "wp-settings-time-\d+=[^;]+(; )?", "");
  set req.http.cookie = regsuball(req.http.cookie, "wordpress_test_cookie=[^;]+(; )?", "");
  if (req.http.cookie == "") {
    unset req.http.cookie;
  }

}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
  if (beresp.ttl == 120s) {
    set beresp.ttl = 1h;
  }
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}

Modification de la configuration de Apache

Nous avons vu dans la configuration qu’Apache serait placé en écoute sur le port 8080, nous allons donc modifier sa configuration.

/etc/apache2/ports.conf

Listen 8080  # on modifie 80 en 8080

/etc/apache2/sites-available/*.conf

<VirtualHost *:8080>

On passe sur 8080 tous les VirtualHost des fichiers configuration d’Apache (hors default-ssl.conf).

Gestion des logs

Tel quel, Apache va enregistrer tous le trafic comme provenant de 127.0.0.1. Afin d’indiquer la bonne source nous devons créer un nouveau format de log dans /etc/apache2/apache2.conf que l’on ajoutera à la suite des autres.

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnishcombined

Puis on éditera à nouveau les VirtualHost pour leur indiquer d’utiliser ce nouveau format de log.

CustomLog /var/log/apache2/monsite.log varnishcombined

Déploiement de Varnish

Tout est à présent configuré, il faut redémarrer Apache et Varnish pour prendre en compte les modifications.

$ service apache2 restart
$ service varnish restart

Il ne reste plus qu’a accéder aux différents sites du serveur afin de s’assurer que tout fonctionne.

Problème rencontré

Lors de la mise en place de Varnish, je suis tombé sur le problème suivant : Varnish resté bloqué sur le port 6081 et ne voulais pas prendre en compte le port 80 indiqué dans la configuration. C’est une chose que l’on peut très vite contrôler avec la commande suivante :

$ sudo netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:6081            0.0.0.0:*               LISTEN      20095/varnishd
tcp        0      0 127.0.0.1:6082          0.0.0.0:*               LISTEN      20094/varnishd
tcp6       0      0 :::6081                 :::*                    LISTEN      20095/varnishd
tcp6       0      0 :::8080                 :::*                    LISTEN      17662/apache2
tcp6       0      0 :::443                  :::*                    LISTEN      17662/apache2

Malgré plusieurs redémarrage, Varnish écouté toujours sur le port 6081. Voici la solution trouvé sur How to: Varnish listen port 80 with systemd. En gros, il existe deux fichiers de configuration qui sont utilisés suivant la façon dont est appelé le service. Pour corriger ce probleme, il faut donc que ces deux fichiers indiquent la même chose :

$ cp /lib/systemd/system/varnish.service /etc/systemd/system/
$ vi /etc/systemd/system/varnish.service
[Unit]
Description=Varnish HTTP accelerator

[Service]
Type=forking
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStartPre=/usr/sbin/varnishd -C -f /etc/varnish/default.vcl
ExecStart=/usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
ExecReload=/usr/share/varnish/reload-vcl

[Install]
WantedBy=multi-user.target

Dans ce fichier, on remplace le port 6081 part le port 80. Il ne reste qu’a recharger Varnish et tout rentre dans l’ordre.

systemctl reload varnish.service

Gain de performance apporté par Varnish

Afin de mesurer le gain de performance apporté par la mise en place de Varnish, on réalise une serie de tests. Attention, les résultats de ces tests sont très dépendant du serveur et du type de site qui y tournent. Dans notre cas on testera le gain de performance apporté par Varnish pour un site WordPress installé sur un serveur VPS SSD d’OVH.

Pour le benchmark du serveur, on utilise le stress test pour Apache Siege. Il a été préféré à Apache Benchmark car il offre la possibilité de tester une liste d’url au lieu d’une page unique.

$ siege -c 2 -t60s -f url.txt -i -q

Toute une série de test a été lancée sur un fichier contenant 10 url en faisant varier la concurrence de 1 à 20. Les résultats sont visibles sur le graphique ci-dessous.

Comme on le remarque, les performance du serveur avec Varnish sont meilleurs. Cela se confirme d’autant plus lorsque la concurrence augmente.

Le gros apport de Varnish se situe au niveau du temps de réponse. Il reste en effet stable à 0.01 sec quelque soit la concurrence tandis qu’il augmente fortement lorsque Apache est utilisé seul (démarrant à 0.13s pour grimper jusqu’à 1,58s).

Laisser un commentaire

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