19

Booster Apache avec Varnish! votre blog wordpress vous en remerciera

Salut les lecteurs!

bon, ces derniers temps Apache donnait des gros signes de fatigue dû à l’augmentation du trafic du blog :(
alors j’ai cherché à l’optimiser au mieux, et encherchant sur la toile des infos je suis tombé sur varnish :)

En gros Varnish met en cache les pages visitées.
Lors d’une nouvelle visite sur les pages déjà vue, Varnish distribue les pages sans solliciter Apache. Ce qui permet d’avoir beaucoup plus de connexion simultané.
Attention, Vanish n’accélère pas le chargement des pages mais « juste » une plus grande disponibilité du serveur Web.

Nous allons voir l’installtion et la configuration de varnish.

Installation:(cas pour Ubuntu)

$sudo apt-get install varnish

après que le paquet soit installer nous allons passer à la configuration

premier fichier de conf à modifier: /etc/varnish/default.vlc

$sudo nano /etc/varnish/default.vlc
backend blog {
        .host = "127.0.0.1";
        .port = "8080";
        .connect_timeout = 1s;
        .first_byte_timeout = 5s;
        .between_bytes_timeout = 2s;
}

sub vcl_recv {
  # Rules for all requests

  # Only the blog URL is cached
  if (req.http.host ~ "(memo-linux.com)") { set req.backend = blog; }
  else { return (pass); }

  # Compatiblity with Apache log
  remove req.http.X-Forwarded-For;
  set    req.http.X-Forwarded-For = client.ip;

  # Post requests will not be cached
  if (req.request == "POST") {
    return (pass);
  } 

  # Normalize encoding/compression
  if (req.http.Accept-Encoding) {
    if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip";     }
    elsif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; }
    else { remove req.http.Accept-Encoding; }
  }

  # Remove has_js and Google Analytics __* cookies.
  if (req.http.cookie) {
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
    # Remove a ";" prefix, if present.
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
    # Remove empty cookies.
    if (req.http.Cookie ~ "^\s*$") {
      unset req.http.Cookie;
    }
  }

  # Serve the page
  unset req.http.vary;
  # If I am logged in to wordpress, I DO NOT WANT TO SEE cached pages
  if ( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ) {
    return (pass);
  } else {
 # If I'm just a regular visitor
    # If the request is static
    if (req.url ~ "\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)$") {
      # Remove the cookie and make the request static
      unset req.http.cookie;
      return (lookup);
    }
    # Try to lookup in the cache
    return (lookup);
  }

  # Cookie ? Not cacheable by default
  if (req.http.Authorization || req.http.Cookie) {
    return (pass);
  }

  # if host header is empty return 404
  error 404 req.http.host;
  return (lookup);
}

sub vcl_fetch {
  if (req.http.host ~ "(memo\-linux\.com)") {
    # Do not cache POST requests
    if (req.request == "POST") {
   return (pass);
    }
    # If the request is static
    if (req.url ~ "\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)$") {
      # Cache it, and make it last 2 hours
      set beresp.ttl = 7200s;
      # Make the request static by removing any cookies set by those static files
      unset beresp.http.set-cookie;
      # Deliver the cached object
      return (deliver);
    }
    # If I am logged in to wordpress, I DO NOT WANT TO SEE cached pages
    if (req.http.cookie ~ "wordpress_logged_in") {
      return (pass);
    } else {
      # Cache anything for 2 minutes. When the cache expires it will be cached again and again, at the time of the request
      set beresp.ttl = 120s;
      return (deliver);
    }
  }
}

sub vcl_deliver {
  # Secure the header
  remove resp.http.Via;
  remove resp.http.X-Varnish;
  remove resp.http.Server;
  remove resp.http.X-Powered-By;
}

vous pouvez copier mon fichier en modifiant évidemment l’url du blog.

et on va éditer le fichier /etc/default/varnish

$sudo nano /etc/default/varnish

je vous colle juste les lignes à modifier:

# Should we start varnishd at boot?  Set to "yes" to enable.
START=yes

il faut passer START à yes sinon, le démon varnish de démarre pas
et voici la seconde partie à modifier, vous pouvez recopier mon fichier(pour un 4 core):

DAEMON_OPTS="-a :80
-T localhost:6082
-f /etc/varnish/default.vcl
-S /etc/varnish/secret
-p thread_pool_add_delay=2
-p thread_pools=4
-p thread_pool_min=200
-p thread_pool_max=4000
-p cli_timeout=25
-p session_linger=100
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"

Maintenant, nous allons nous occuper d’Apache
on édite le fichier /etc/apache2/ports.conf et on modifie 80 par 8080

$sudo nano /etc/apache2/ports.conf
NameVirtualHost *:8080
Listen 8080

ensuite on va modifier nos virtualhost qui vont écouter sur le port 8080

$sudo nano /etc/apache2/site-avaiables/default
<VirtualHost *:8080>
        ServerAdmin fred@memo-linux.com
        ServerNAme memo-linux.com
        DocumentRoot /var/www
        CustomLog /var/log/apache2/memo-linux.log varnishcombined
....
</virtualhost>

la ligne CustomLog /var/log/apache2/votreblog.log varnishcombined est à ajouter

maintanant on a éditer le fichier de conf d’Apache, pour pouvoir récupérer les adresse IP de nos visiteur, car là il ne récupère que l’adresse indiquée dans default.vlc

$sudo nano /etc/apache2/apache.conf

et on ajoute:

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

et pour finir on restart apache et varnish

$sudo /etc/init.d/apache2 restart
$sudo /etc/init.d/varnish restart

commandes utiles:
varnishlog: Affichage du log du daemon Varnish.
varnishstat: Affichage des statistiques d’utilisation de Varnish.
varnishhist: Affiche un historique sous forme de graphe des requêtes faites à votre serveur Varnish.
varnishadm: une interface d’administration locale de Varnish

et voilà, si ça peut aider! :-)

ASTUCE: si la capture des adresses clientes ne fonctionnent pas avec X-Forwarded-for, installer ceci:

$sudo apt-get install libapache2-mod-rpaf

et là fonctionne à coup sûr!!!

source: http://blog.nicolargo.com/2010/10/booster-votre-blog-wordpress-avec-varnish.html

Partager l'article :





fred

"Dire que l'on s'en fiche du droit à la vie privée sous prétexte qu'on a rien à cacher, c'est comme déclarer que l'on se fiche du droit à la liberté d'expression sous prétexte qu'on a rien à dire." Edward Snowden

19 commentaires

  1. Hop je te repique le test du cookie vide (req.http.Cookie ~ « ^\s*$ ») qui fonctionnait moyennement chez moi.

    A mon tour maintenant, en espérant que ca puisse t’aider ou au moins t’éviter des sueurs froides : tu a mis 4 pools de thread, je suppose donc que tu a 4 core sur ton serveur. Largement suffisant pour encaisser un apache et un varnish sur la meme machine pour des sites à traffic moyen. Par contre tu devrais faire gaffe au thead_pool_min et thread_pool_max. 4 pools de 200 threads devrait te blinder 4 ou 5 gig de memoire au démarrage, ne le laisse pas monter les pools à 4000 threads si non ta bécane peut péter en cas de montée rapide en charge.
    Cela dit, tu peux dormir sur tes 2 oreilles avec l’architecture que tu as, ça bombarde Varnish.

  2. Salut à toi Guilux!
    merci pour ta remarque, effectivement je n’ai pas précisé que c’est pour un 4 core.
    Pour un bi avec 4Go de RAM, que penses-tu des ces réglages:
    [code]
    thread_pools=2
    -p thread_pool_min=50
    -p thread_pool_max=1000
    [/code]

  3. Ca ne marche pas chez moi, le port 8080 est déjà utilisé. Et j’ai essayé d’utiliser le 80, mais ça marche pas mieux, j’ai une erreur bizarre. >-<
    Et d'ailleurs c'est quoi ton plugin de captcha ?

  4. salut Mouffles!

    pour le port tu peux utiliser celui que tu veux, exemple: 1080
    n’oublie pas d’autoriser ce port dans iptables pour 127.0.0.1

    Que utilises-tu sur le port 8080, un proxy?

    le but de la manœuvre est pour chaque interrogation d’une page web, il faut que ce soit varnish qui s’en occupe donc obligatoirement varnish sur le port 80 et le serveur web sur un autre port non utilisé.
    N’oublie pas lors du choix du port, de renseigner ce dernier dans la conf de ton serveur web.

    le captcha: Really Simple CAPTCHA

  5. Salut Fred,

    très bon article. Je débute avec Varnish et je voulais savoir s’il était possible, par scripting Varnish, de faire de la redirection en fonction d’un « mot » présent, dans l’url (ou dans l’entête, au choix), si ce mot est trouvé dans un fichier.
    Exemple : j’ai un serveur en Production et un autre préProduction, chacun ayant leur version de mon appli web. Des clients se connectent à l’un ou l’autre de mes serveurs (de facon exclusive). Je compte donc mettre un Varnish en proxy pour rediriger les requetes. La redirection doit prendre en compte le numéro unique affecté à chacun de mes clients, numéro que je peux ajouter à l’url ou dans l’entête de la requete envoyée par le client. Un fichier, au niveau de Varnish, contiendrait la liste des numéros uniques pour lesquels la requête doit être redirigée vers le serveur de préProduction.

    Ma question est donc : est ce que, au niveau de Varnish, je peux, sur requête entrante, récupérer soit une partie de l’url, soit une info dans le header et lire un fichier pour vérifier si cette info y est présente ? Selon le résultat, je renvoie la requête vers le serveur de Prod ou celui de préProd.

    Merci d’avance pour ta réponse ou à celui qui saurait me répondre.

  6. Salut Bi30,
    ça ne serait pas plus simple de passer par un sous domaine?
    Avec un sous domaine pour chaque serveur (prod. et postprod.) c’est beaucoup plus facile pour la configuration de varnish.

  7. Merci Fred pour la rapidité de ta réponse mais soit je ne suis pas sur d’avoir compris ta solution, soit je me suis mal exprimé sur la configuration à laquelle je suis confronté.
    Je vais donc essayer de reformuler :
    – j’ai actuellement une appli Web hébergée sur un serveur, dans un datacenter.
    – j’ai des clients (en fait des périphériques), hors du datacenter, qui se connectent à mon appli.
    – pour pouvoir tester de nouvelles versions du soft de mon appli ou du soft de mes périphériques, je souhaite ajouter dans le datacenter un autre serveur avec une version de préProduction de mon appli web.
    – je souhaite pouvoir « basculer » certains de mes périphériques vers la version Prod ou préProd de mon appli SANS AVOIR A CHANGER L’URL DU SERVEUR SUR CES PERIPH, c’est pourquoi j’ai pensé à un proxy en frontal des serveurs Prod et préProd, qui aurait la liste des périph qui doivent être rootés vers le serveur de préProd (à défaut, vers le serveur de Prod). Ainsi, il suffirait d’ajouter ou de retirer un périph (i.e. l’identifiant unique) de cette liste pour orienter sa requête vers le serveur de préProd ou de Prod, sans avoir à reconfigurer l’url sur le périph.
    J’espère avoir été plus clair.
    Entre temps, j’ai vu que sur la version 3 de Varnish, il existait une commande ‘fileread’ pour lire un fichier, et vu qu’il est possible de tester le contenu de l’url ou du header, je me dis que je devrais pouvoir faire quelque chose.
    Cdlt.

  8. J’avais bien saisie ton problème sauf l’impératif de ne pas changer l’URL, d’ou ma proposition de sous domaine.

    Là dans ton cas précis je n’ai pas de solution.
    De plus, (je m’avance peut-être un peu, enfin de ce que je sais) ce n’est pas une url de type « mondomaine.com/index.php?turcmuch12345 » qui va pointer sur une adresse IP mais juste « mondomaine.com ».

    J’espère que tu vas trouver une solution à ton problème, désolé de ne pas t’aider d’avantage…

  9. En fait, le plus simple pour moi est d’avoir une info dans le header (n° du périph) de la requête. Comme je le disais auparavant, j’explore la piste du fichier que lirait Varnish et qui contiendrait les n° de périph qu’il faut orienter vers le serveur de préProd.
    Si j’ai une solution qui fonctionne, je rajouterai un commentaire ici au cas où quelqu’un aurait le même besoin que moi.
    En attendant merci beaucoup pour tes réponses.
    Cdlt.

  10. Malheureusement, je ne vais pas publier ici une solution avec Varnish. En fait, je me suis rendu compte que, comme le fichier de configuration de Varnish (.vcl) est compilé au lancement de Varnish, les comparaisons (if … else …) sont fait avec des chaines de caractères statiques et non pas dynamiques (i.e. lecture d’un fichier avec la method ‘fileread’ sur réception d’une requête).
    Je m’oriente donc plutot vers de l’Apache avec la directive RewriteMap du module mod_rewrite. J’aurai peut être plus de succès.
    Toutefois, il serait intéressant qu’une version future de Varnish permette de faire du code de comparaison un peu plus « poussé ».

  11. Merci, appliqué en 15mn sur mon serveur dual core :)

  12. Salut Xarkam!

    je me suis pris un peu la tête par la suite car plusieurs sites hébergés avec des rewrite d’URL…
    du coup le fichier n’est plus exactement le même, en tout cas varnish rox bien du poney! :-)

  13. ha, ben justement je vais mettre du url rewriting avec wordpress entre autre. Je serais intéressé le moment venu, soit ici, soit sur g+ ;)

  14. Pensez vous que varnish n’est justifier que sur un site à gros traffic, ou apprter un gain, même si le traffic n’est pas important?

  15. Quoiqu’il en soit il y a forcément un gain, vu que varnish est là pour soulager le serveur web/php. Et mieux vaut prévenir que guérir, dans le sens ou si par chance le site/blog connait des piques d’influences très important, dans ce cas on sera bien content que Varnish soit installer et configurer.

  16. Hey ! Merci pour ce tuto, même si il date un peu ;)
    J’ai trouvé quelques fautes d’orthographes, et ton article doit être encore pas mal visité donc ça peut aider :)
    Voici les commandes corrigées :
    sudo nano /etc/varnish/default.vcl
    sub vcl_fetch {
    if (req.http.host ~ "(memo\-linux\.com)") {
    # Do not cache POST requests
    if (req.request == "POST") {
    return (deliver);
    }
    sudo /etc/apache2/sites-available/default

    A+

  17. Salut Angristan,
    comme je l’ai précisé dans les commentaires, mon fichier vcl a bien changé depuis :-)
    Merci en tout cas ! :-D

Laisser un commentaire

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