Total Pageviews

Tuesday, 15 November 2011

install APC as cache system and configure Varnish as reverse-proxy for Apache to improve performance

Allez, on continue d’optimiser notre serveur : aujourd’hui, je vous montre comment améliorer nettement les performances du serveur.
Nous allons d’abord installer un système de cache – j’ai choisi APC – qui va soulager un peu le système en mettant en cache les pages du site les plus demandées. Cela aura un impact sur le temps de traitement des pages (moins de traitement PHP) et sur la base de données (moins de requêtes SQL).
Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse proxy pour Apache pour améliorer les performances
Dans un second temps, nous installons Varnish comme reverse-proxy pour Apache : tous les objets statiques (images, CSS, JS) seront traités par Varnish, le reste (PHP) sera traité par Apache. Cela divise sensiblement la charge serveur.

Installation d’APC

APC est un système de cache que je trouve très performant. On l’installe avec :
pecl install apc
puis on crée le fichier de configuration :
nano /etc/php5/conf.d/apc.ini
et on y ajoute :
extension=apc.so
apc.enabled=1
apc.shm_size=30

Si vous avez une erreur de compilation lors de l’installation d’APC, c’est sûrement que le paquet libpcre3-dev n’est pas installé. Dans ce cas :
aptitude install libpcre3-dev
Il ne reste plus qu’à relancer Apache :  :
/etc/init.d/apache2 restart
A noter qu’APC est livré avec un script PHP (nommé apc.php) qui vous permet de voir quelques statistiques sur la mise en cache de vos fichiers. Petit exemple de ce que cela donne :
Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse proxy pour Apache pour améliorer les performances
Pour installer apc.php, il faut le copier le fichier à la racine de notre site :
cp /usr/share/doc/php-apc/apc.php /home/skyminds/public_html/
puis l’éditer :
nano /home/skyminds/public_html/apc.php
pour y modifier le mot de passe :
defaults('ADMIN_USERNAME','apc');              // Admin Username
defaults('ADMIN_PASSWORD','password');     // Admin Password - CHANGE THIS TO ENABLE!!!
Voilà, APC est installé et actif.

Installation de Varnish

Passons maintenant à l’installation du serveur Varnish :
wget http://repo.varnish-cache.org/debian/GPG-key.txt
apt-key add GPG-key.txt 
echo "deb http://repo.varnish-cache.org/debian/ lenny varnish-2.1" >> /etc/apt/sources.list
aptitude update
aptitude install varnish
Principe de fonctionnement : Varnish va écouter sur le port 80. C’est lui qui va traiter toutes les requêtes : il va transmettre à Apache (sur le port 8080) tout ce qui est dynamique (PHP etc) et s’occupera lui-même des fichiers statiques (images, javascripts etc).
Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse proxy pour Apache pour améliorer les performances
Cela va donc alléger notre serveur Apache et nous allons pouvoir mettre en cache tous les éléments statiques.
On configure le serveur Varnish en éditant le fichier de configuration :
nano /etc/default/varnish
Dans ce fichier, naviguez jusqu’à l’alternative #2 et changez le port 6081 en 80 (première ligne) :
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
Le fichier varnish_storage.bin sera limité à 1 Go, sachant que ma Kimsufi possède 2 Go de RAM. Comme Varnish tourne maintenant sur le port 80, il faut maintenant forcer Apache à écouter sur le port 8080. On édite donc :
nano /etc/apache2/ports.conf
et on change toutes les références à 80 en 8080 :
NameVirtualHost *:8080
Listen 8080
Passons maintenant à la configuration de notre site dans Varnish et éditons /etc/varnish/default.vcl :
nano /etc/varnish/default.vcl
on y met :
/* ------------------------------------------------------------ */
/*        VCL Configuration by Matt - www.skyminds.net          */
/* ------------------------------------------------------------ */
 
# Redirect requests to Apache
backend www {
   .host = "127.0.0.1";
   .port = "8080";
   .connect_timeout = 600s;
   .first_byte_timeout = 600s;
   .between_bytes_timeout = 600s;
}
 
# Called after a document has been successfully retrieved from the backend.
sub vcl_fetch {
        # set minimum timeouts to auto-discard stored objects
        set beresp.grace = 5m;
        if (beresp.ttl < 8h)
        {
                set beresp.ttl = 8h;
        }
       if (req.url ~ "\.(png|gif|jpg|swf|css|js)$")
        {
                unset beresp.http.set-cookie;
        }
 
       ## Deliver the content
       return(deliver);
}
 
sub vcl_recv {
 
        # Serve objects up to 5 minutes past their expiry if the backend is slow to respond.
        set req.grace = 5m;
 
        # Compatiblity with Apache log
        remove req.http.X-Forwarded-For;
        set req.http.X-Forwarded-For = client.ip;
 
        if (req.http.host ~ "^(www\.)?skyminds\.net$")
        {
                set req.backend = www;
        }
 
        ### always cache these images & static assets & Remove cookies and query string for real static files
        if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|rar|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$")
        {
                unset req.http.cookie;
                set req.url = regsub(req.url, "\?.*$", "");
        }
 
        # Normalize Content-Encoding
        if (req.http.Accept-Encoding)
        {
                if (req.url ~ "\.(jpg|png|gif|gz|rar|tgz|bz2|lzma|tbz|mp3|ogg)(\?.*|)$")
                {
                        remove req.http.Accept-Encoding;
                }
                elsif (req.http.Accept-Encoding ~ "gzip")
                {
                        set req.http.Accept-Encoding = "gzip";
                }
                elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE")
                {
                        set req.http.Accept-Encoding = "deflate";
                }
                else
                {
                        remove req.http.Accept-Encoding;
                }
        }
 
        ### never cache POST requests
        if (req.request == "POST")
        {
          set req.backend = www;
          return(pass);
        }
 
        return(lookup);
}
et on ouvre les ports dans iptables :
iptables -A OUTPUT -p tcp --dport 8080 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 6082 -s 127.0.0.1 -j ACCEPT
on redémarre pour appliquer les changements :
/etc/init.d/varnish restart
/etc/init.d/apache2 restart

Modification du Virtual Host

Il faut mettre à jour notre virtual host :
nano /etc/apache2/sites-available/www.skyminds.net
Le fichier commence par cette ligne :
<VirtualHost *:80>
On la remplace par :
<VirtualHost *:8080>
# ajout des logs
CustomLog /var/log/apache2/www-access.log varnishcombined
ErrorLog /var/log/apache2/www-error.log
Ensuite, on édite /etc/apache2/apache2.conf :
nano /etc/apache2/apache2.conf
et on y ajoute, en bas du fichier, au niveau des logs :
# VARNISH
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnishcombined
# Access log for VirtualHosts that don't define their own logfile
CustomLog /var/log/apache2/other_vhosts_access.log vhost_combined
et on recharge Apache pour tout prendre en compte :
/etc/init.d/apache2 reload
Voilà, vos fichiers statiques sont mis en cache et servis par Varnish. Les fichiers dynamiques sont servis par Apache et mis en cache avec APC.

Sommaire de la série Monter un serveur dédié de A à Z

  1. Serveur dédié : installation d’Apache, PHP, MySQL et Webmin
  2. Serveur dédié : créer la base de données MySQL et importer WordPress
  3. Serveur dédié : créer et activer un Virtual Host sous Apache
  4. Serveur dédié : changer les DNS du nom de domaine et le faire pointer vers le serveur
  5. Serveur dédié : sécurisation des services avec iptables et fail2ban
  6. Serveur dédié : sécurisation de la couche TCP/IP
  7. Serveur dédié : création d’un serveur mail Postfix (sécurisé avec Saslauthd et certificat SSL) et Courier (accès POP et IMAP) utilisant une base MySQL d’utilisateurs/domaines virtuels
  8. Serveur dédié : sécuriser Apache 2 avec ModSecurity
  9. Serveur dédié : CHMOD récursif sur des fichiers ou répertoires en ligne de commande
  10. Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse-proxy pour Apache pour améliorer les performances
  11. Serveur dédié : afficher la véritable IP derrière un reverse-proxy comme Varnish
  12. Serveur dédié : intégrer SSH à WordPress pour mettre à jour le core, les plugins et les thèmes
  13. Serveur dédié : installer la dernière version d’APC par SVN
  14. Serveur dédié : analyse des performances du serveur
  15. Serveur dédié : mettre à jour le noyau Debian de la Kimsufi
  16. Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde OVH
  17. Serveur dédié : installer la dernière version d’APC par SVN
FROM http://www.skyminds.net/2011/05/07/serveur-dedie-installer-apc-comme-systeme-de-cache-et-configurer-varnish-comme-reverse-proxy-pour-apache-pour-ameliorer-les-performances/
--------------------------------------------------------------------------------------------

Setting up Varnish with Apache


Varnish is an HTTP accelerator designed for content-heavy dynamic web sites. In contrast to other HTTP accelerators, such as Squid, which began life as a client-side cache, or Apache, which is primarily an origin server, Varnish was designed from the ground up as an HTTP accelerator.
Here’s how to set up varnish with Apache.
Tested on Ubuntu 10.04 (Lucid) Server LTS.


1. Install varnish:
sudo apt-get install varnish
2. Configure varnish to serve on 80 and fetch from 8008:
vim /etc/default/varnish

DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G
vim /etc/varnish/default.vcl

backend apache {
        .host = "127.0.0.1";
        .port = "8008";
}
acl purge {
        "localhost";
        "127.0.0.1";
}
sub vcl_recv {
        // Strip cookies for static files:
        if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
                unset req.http.Cookie;
                return(lookup);
        }
        // Remove has_js and Google Analytics __* cookies.
        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;
        }
        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url ~ " req.url " && req.http.host == " req.http.host);
                error 200 "Purged.";
        }
}
sub vcl_hash {
  if (req.http.Cookie) {
    set req.hash += req.http.Cookie;
  }
}
sub vcl_fetch {
        // Strip cookies for static files:
        if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
                unset beresp.http.set-cookie;
        }
        // Varnish determined the object was not cacheable
        if (!beresp.cacheable) {
                set beresp.http.X-Cacheable = "NO:Not Cacheable";
        } elsif(req.http.Cookie ~"(UserID|_session)") {
            // You don't wish to cache content for logged in users
                set beresp.http.X-Cacheable = "NO:Got Session";
                return(pass);
        }  elsif ( beresp.http.Cache-Control ~ "private") {
                 // You are respecting the Cache-Control=private header from the backend
                set beresp.http.X-Cacheable = "NO:Cache-Control=private";
                return(pass);
        } elsif ( beresp.ttl < 1s ) {
                // You are extending the lifetime of the object artificially
                set beresp.ttl   = 300s;
                set beresp.grace = 300s;
                set beresp.http.X-Cacheable = "YES:Forced";
        }  else {
                // Varnish determined the object was cacheable
                set beresp.http.X-Cacheable = "YES";
        }
        return(deliver);
}
4. Set apache to listen on port 8008:
vim /etc/apache2/ports.conf

NameVirtualHost *:8008
Listen 8008
 
5. Set all vhosts to listen on port 8008:
vim /etc/apache2/sites-enabled/000-default <Virtualhost *:8008> ... </Virtualhost> Do the same for all other vhosts.
6. Restart Apache and Varnish:
service apache2 restart service varnish restart 7. Test varnish:
curl -I http://www.euperia.com/linux/setting-up-varnish-with-apache-tutorial/ HTTP/1.1 200 OK Server: Apache X-Pingback: http://www.euperia.com/xmlrpc.php Link: ; rel=shortlink Vary: Accept-Encoding,User-Agent Content-Type: text/html; charset=UTF-8 X-Cacheable: YES Content-Length: 22992 Date: Wed, 05 Jan 2011 22:01:22 GMT X-Varnish: 769719461 769719459 Age: 7 Via: 1.1 varnish Connection: keep-alive Notice the Varnish headers? There are also a couple of these. Age shows the age of the item in the Varnish cache.

Links

A good set of links can be found here:

Update: 17th Feb 2012

There is also a great set of instructions over at ocaoimh.ie.

from http://www.euperia.com/website-performance-2/setting-up-varnish-with-apache-tutorial/299