12 étapes pour optimiser les performances de son blog WordPress
Date: 6/09/2010 | Catégories: Blog,Open-source,Systeme,Web | Tags: apache,memcached,mysql,planet-libre,wordpress
Lorsque l'on choisi d'héberger son blog WordPress (sur un serveur dédié ou virtuel), la problématique des performances vient assez vite sur le tapis. En effet, l'optimisation du blog permet non seulement de réduire le temps de chargement des pages (et donc d'être bien vu par seigneur gOOgle) mais également de dimensionner au plus juste son serveur: gain de temps d'un coté, gain d'argent de l'autre.
Nous allons donc dans ce billet parcourir une liste non exhaustive de techniques d'optimisations:
- ETAPE 1: Hardware
- ETAPE 2: Noyau Linux
- ETAPE 3: Mise à jour du système d'exploitation
- ETAPE 4: MemCached
- ETAPE 5: Les modules Apache
- ETAPE 6: Configuration d'Apache
- ETAPE 7: XCache (PHP)
- ETAPE 8: MySQL
- ETAPE 9: WP-DBManager
- ETAPE 10: W3 Total Cache
- ETAPE 11: Thème WordPress
- ETAPE 12: Tester/Surveiller
Les commentaires seront bien sur là pour nous faire partager vos solutions !
Le hardware
ETAPE 1) C'est un peu le serpent qui se mort la queue... En effet il est assez difficile de dimensionner le hardware d'un serveur sans avoir fait les optimisations est sans connaitre précisément le trafic du blog (surtout vrai pour les nouveaux blog).
C'est en partie pour ces raisons qui j'ai choisi un serveur VPS de chez Gandi. En effet il est possible d'augmenter ou de diminuer les "parts" affectées à son serveur de manière dynamique (une "part" correspond à une ressource CPU, mémoire et disque).
J'ai actuellement "3 parts" sur le serveur du Blog de Nicolargo mais je m'en sers également pour d'autres besoins (je pense que pour ce blog, un serveur avec "2 parts" suffirait largement). Pour une première expérience dans le monde du blogging, un serveur "1 part" devrait convenir (environ 12€ HT par mois).
Je n'entrerai pas dans les discussions sur le coups relativement élevé de cette solution par rapport à un serveur dédié comme l'offre Dedibox de Online.net.
Le système d'exploitation
L'optimisation du système d'exploitation dépend bien sûr de la distribution Linux utilisée. Lors de la création de mon serveur j'ai choisi d'utiliser Ubuntu Server 8.04 que j'ai fait évolué en 9.04. Pourquoi cette distribution GNU/Linux ? Tout simplement car c'est celle que je connais le plus...
ETAPE 2 ) On commence par optimiser le noyau Linux . Je passe rapidement sur les explications. Il existe de nombreux article sur le net détaillant ces configurations. La configuration donnée est celle de mon serveur VPS (3 parts, 1 Go de RAM), elle doit être adaptée à votre configuration hardware.
Il faut éditer/modifier le fichier /etc/sysctl.conf (disponible sur GitHub):
Puis on applique:
sudo sysctl -p
Sources:
ETAPE 3) La première chose à faire quand on administre un serveur est bien entendu de le maintenir à jour au niveau des logiciels systèmes et applicatifs. Pour cela je m'aide d'un petit logiciel nommé cron-apt. Ce dernier permet de m'avertir par mail quand une mise à jour est disponible (par exemple une nouvelle version d'Apache ou une librairie PHP). En plus de corriger des failles de sécurités, les mises à jours permettent souvent d'obtenir de meilleures performances (que ce soit en rapidité ou en consommation de ressources).
L'installation est des plus simple:
sudo aptitude install cron-apt
Configuration en éditant le fichier /etc/cron-apt/config, notamment les lignes suivantes:
MAILTO="nom@domaine.com"
MAILON="always"
Un mail sera automatiquement envoyé à l'adresse nom@domaine.com, tout les matins à 4:00. Voici un exemple:
On peut voir qu'une mise à jour est disponible. Il ne reste plus qu'a se connecter en SSH sur le serveur et faire un:
sudo aptitude safe-upgrade
Il est possible de faire automatiquement les mises à jour mais je pense cela risqué si quelque chose se passe mal...
On critique souvent les serveurs VPS pour leurs faibles performances disque. Bien que je trouve celle des VPS Gandi plutôt acceptable (environ 6 Mo/s pour l'écriture et 24 Mo/s pour la lecture de petits fichiers type script PHP), il est intéressant de mettre en place un cache mémoire sur notre serveur. Ainsi, les applications compatibles pourront lire et écrire les données en RAM et non plus sur disque.
ETAPE 4) Nous allons donc installer MemCached, un cache mémoire libre. On commence par installer le cache ainsi que la librairie Perl associée (qui sera utilisée par WordPress):
sudo aptitude install libcache-memcached-perl php5-memcache memcached
Par défaut, le cache écoute sur l'adresse 127.0.0.1 et sur le port TCP/11211. La taille du cache mémoire est de 64 Mo. J'ai gardé ces paramètres pour mon utilisation.
On peut obtenir des statistiques sur l'utilisation de MemCached en utilisant la commande:
# echo "stats" | nc localhost 11211
STAT pid 2806
STAT uptime 698465
STAT time 1283351366
STAT version 1.2.2
STAT pointer_size 32
STAT rusage_user 31.829989
STAT rusage_system 123.891742
STAT curr_items 12834
STAT total_items 1394993
STAT bytes 48830599
STAT curr_connections 11
STAT total_connections 16845
STAT connection_structures 31
STAT cmd_get 4012823
STAT cmd_set 1394993
STAT get_hits 2547543
STAT get_misses 1465280
STAT evictions 5694
STAT bytes_read 10561103955
STAT bytes_written 37908972470
STAT limit_maxbytes 67108864
STAT threads 1
END
Apache & PHP
On continue ensuite avec l'optimisation du serveur Apache (version 2.xx au moment de l'écriture de ce billet).
ETAPE 5) Apache se base sur un système de modules pour ajouter de nouvelles fonctions à votre serveur Web. Sous Ubuntu Server, la liste des modules actifs se trouvent dans le répertoire /etc/apache2/mods-enabled. Un petit ls dans ce répertoire vous donne donc la liste. L'optimisation consiste à supprimer les modules non utilisés. Je vous conseille la lecture de ce billet qui donne la liste des modules nécessaires au fonctionnement de WordPress. Attention, si votre serveur héberge d'autres sites Web que votre blog, il faut vérifier de ne pas supprimer un module utile...
Voici la liste de mes modules sur mon serveur:
alias.conf autoindex.conf dir.conf negotiation.load
alias.load autoindex.load dir.load php5.conf
auth_basic.load cgi.load env.load php5.load
authn_file.load dav.load expires.load rewrite.load
authz_default.load dav_svn.conf headers.load setenvif.conf
authz_groupfile.load dav_svn.load mime.conf setenvif.load
authz_host.load deflate.conf mime.load status.conf
authz_user.load deflate.load negotiation.conf status.load
ETAPE 6) On configure ensuite la manière dont les processus Apache sont lancés et gérés en mémoire et d'autres paramètres. Il faut éditer la section suivante dans le fichier /etc/apache2/apache2.conf (ou httpd.conf sur d'autre distribution GNU/Linux). Pour une description des paramètres, merci de lire le billet suivant:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 40
MaxRequestsPerChild 2000
</IfModule>
# KeepAlive: Whether or not to allow persistent connections
KeepAlive On
# MaxKeepAliveRequests: The maximum number of requests to allow
MaxKeepAliveRequests 200
# KeepAliveTimeout: Number of seconds to wait for the next request
KeepAliveTimeout 5
# Timeout: The number of seconds before receives and sends time out.
Timeout 50
J'ai également modifier le fichier /etc/apache2/conf.d/optimization pour gagner quelques précieux points aux tests Yslow et Page Speed:
Header unset ETag
FileETag None
On applique la configuration en relançant Apche:
sudo /etc/init.d/apache2 restart
Sources:
ETAPE 7) WordPress se base sur le langage PHP qui est connu pour être flexible mais pas très performant. C'est pour cela qu'il est nécessaire d'installer un cache PHP sur votre serveur Web WordPress. En gros, il permet de mettre en cache le code PHP déjà compilé. J'utilise personnellement XCache.
L'installation est simple:
sudo aptitude install php5-xcache
On configure ensuite le fichier/etc/php5/conf.d/xcache.ini (à adapter à votre configuration):
xcache.size = 64M
On relance le serveur Web:
sudo /etc/init.d/apache2 restart
Source:
MySQL
Souvent décriée, MySQL reste à l'heure actuelle la base de donnée officielle supportée par le moteur de blogging WordPress. Nous allons donc étudier quelques techniques d'optimisation.
ETAPE 8) On commence par éditer le fichier de configuration /etc/mysql/my.cnf pour ajuster la taille des caches (encore une fois les valeurs sont à adapter en fonction de votre audience/configuration):
query_cache_type = 1
query_cache_limit = 2M
query_cache_size = 32M
ETAPE 9) On installe ensuite le plugin WordPress WP-DBManager. Ce dernier permet de maintenir une base de données optimisée à travers le temps. En plus des fonctions de sauvegarde (manuelle ou automatique) et de restauration de votre base de données WordPress, ce plugin permet de d'optimiser et réparer cette même base.
Source:
WordPress
ETAPE 10) L'installation standard de WordPress (la fameuse installation en 5 minutes) ne tient pas en compte de l'optimisation. Nous allons voir comment configurer l'utilisation parallèle de XCache et Memcached (préalablement installé dans les étapes n°3 et n°5). Pour cela nous allons utiliser l'indispensable plugin W3 Total Cache.
Après l'installation du plugin, il faut se rendre dans le menu Performance > General setting de la page d'administration de WordPress puis cliquer sur le bouton Compatibility check pour vérifier que XCache et Memcached sont bien détectés:
Opcode cache: XCache
Memcache extension: OK
Ensuite on configure WordPress pour utiliser Memcached en activant toutes le fonctions de cache (CDN mis à part) et en utilisant le démon Memcached. Exemple de configuration pour les pages:
Dans le menu Page cache settings j'active toutes les fonctions sauf pour les pages 404:
Dans le menu suivant (Minify settings), j'active toutes les fonctions. Cela à pour but d'optimiser les pages, css et js avant d'être envoyés vers les lecteurs (attention, certains JS n'aiment pas beaucoup ces optimisations, à tester donc...).
Enfin, dans le menu Browser Cache setting, j'active toutes les fonctions et les expires header lifetime à:
- 3600 secondes pour JS / CSS
- 3600 secondes pour le HTML
- 2592000 secondes pour les autres fichiers
A l'heure actuelle, le trafic généré par mon blog ne nécessite pas l'utilisation de caches réseau répartis (CDN). Mais c'est une optimisation à prendre en compte pour les "gros" sites.
Sources:
ETAPE 11) Rien ne sert d'avoir un kernel Linux, un serveur Web, un moteur PHP et un WordPress optimisés si le thème de votre blog est mal développé. Il est important de tester ce thème et notamment les plugins utilisées. Ces derniers utilisent souvent des JavaScripts qui peuvent pénaliser fortement le temps de chargement de vos pages. Rien de tel que des mesures de type YSlow et Page Speed pour mettre en évidence ce qui ne va pas.
Sources:
Tester/surveiller son serveur
ETAPE 12) Pour tester les optimisations mise en place, j'utilise l'outil GTMetrix qui donne les valeurs YSlow et Page Speed (avec un archivage vous permettant de voir l'évolution des performances de votre blog à travers le temps).
De manière locale et surtout pour valider la configuration de votre serveur Web (Apache dans ce document), vous pouvez utiliser la commande suivante:
ab -t30 -c5 http://blog.mondomaine.com/
La ligne intéressante donnant le nombre maximal de requête par seconde que votre blog peut supporter est la suivante:
Requests per second: 158.19 [#/sec] (mean)
A un niveau plus bas, la commande Linux netstat permet de donner pas mal d'informations sur l'état des sockets:
netstat -tan | grep ':80 ' | awk '{print $6}' | sort | uniq -c
Enfin, pour surveiller l'activité de MySQL, j'utilise la commande MySqlReport.
Autres optimisations possibles
D'autres optimisations sont possibles, pour vous donner un exemple, je suis tombé l'autre jour sur le première article d'une série en cours sur le blog d'Antoine Benkemoun qui propose d'utiliser Squid pour booster les performances de votre site. C'est une technique très intéressante mais qui nécessite, pour être vraiment efficace, l'utilisation deux deux machines différentes. Une servant de reverse proxy-cache et une autre hébergeant votre blog.
Il est aussi possible de se passer du serveur Web Apache (il est vrai un peu lourd à administrer) pour se pencher vers des serveurs plus légers comme NGinx ou Cherookee. Update: Ou bien d'utiliser NGinx comme serveur Web pour les pages statiques et Apache pour les pages dynamiques (voir exemple de configuration ici). L'avantage d'une telle configuration est un gain non négligeable en terme de consommation mémoire.
Il existe un nombre incalculable d'optimisations possibles, j'espère d'ailleurs en découvrir de nouvelles dans vos commentaires...