Reverse DNS
Les serveurs DNS peuvent mettre du temps à répondre. La première chose que nous allons donc faire est de ne pas rechercher la correspondance texte des adresses IP clientes. Cela se configure très simplement dans la configuration principale /etc/httpd/conf/httpd.conf
1
HostnameLookups Off
Pas de recherche DNS
Comme pour tout ce qui suit, un redémarrage d’apache est nécessaire pour que le paramètre soit pris en compte.
Keep-Alive
Le Keep-Alive est une fonctionnalité datant de la version 1.1 du protocole HTTP qui permet de garder un certain laps de temps la connexion ouverte après qu’une requête soit servie. L’objectif est ainsi de ne pas obliger le client à en ré-ouvrir une connexion s’il a encore besoin de données.
1 2 3 4
KeepAlive on MaxKeepAliveRequests 200 KeepAliveTimeout 10 Timeout 30
paramétrage du keep-alive
Une fois le mode Keep-Alive activé, nous définissons le nombre maximum de requêtes (entendre connexions) concurrent qu’il ne faut pas fermer de suite. Pour déterminer la bonne valeur, nous imaginons ici 50 utilisateurs qui lancent 4 requêtes simultanées par navigateur pour charger leur page. Pour les satisfaire il va nous falloir garder 50*4=200 connexions ouvertes.
Ensuite viennent deux TimeOut, le premier va déterminer le temps (en secondes) avant qu’une connexion soit fermée faute de demande, et le second, le temps (en secondes) pour fermer une connection ouverte mais qui n’a pas été utilisée (ex. le GET n’est jamais arrivé). Ces deux paramètres sont à régler selon votre inspiration.
Les liens symboliques
Le système de fichier sur lequel apache va puiser ses données n’est pas sans impact sur les performances. D’un point de vue général il est bon d’éviter les liens symboliques car sinon apache devra effectuer un appel système supplémentaire par partie de nom de fichier pour résoudre ce lien.
1 2 3
<Directory/> Options -FolllowSymLinks -SymLinksIfOwnerMatch </Directory>
Refus des liens symboliques
.htaccess
Ensuite vient le problème des fichiers .htaccess. En effet, apache va par défaut chercher un tel fichier dans chaque dossier traversé. Ce comportement s’il n’est pas souhaité peut être bloqué, par dossier, comme ceci :
1 2 3
<Directory/> AllowOverride None </Directory>
Refus des .htaccess
Dossiers réseau
Les deux options qui suivent, non seulement ont un impact sur les performances, mais aussi sur la stabilité d’apache. En effet, par défaut le coco se débrouille assez mal avec les systèmes de fichier réseau (NFS, CIFS, etc.). Pour éviter ces soucis, nous devons désactiver soit par dossier (avec une directive Directory) soit globalement, l’utilisation du memory-mapping et de l’appel à la fonction SendFile :
1 2
EnableMMAP off EnableSendFile off
Pour les systèmes de fichier réseau
Multi-Processing Modules
Apache dispose d’un système évolué de gestion des requêtes concurrentes par greffon. Sous Linux nous disposons principalement du module worker et du module prefork. prefork fonctionne à l’ancienne mode unixienne, chaque requête est prise en charge par un serveur qui est hébergé dans son propre processus. Worker quant à lui fait la même chose mais en utilisant un thread à la place du processus. D’un point de vue vitesse, l’utilisation de l’un ou de l’autre n’est pas très déterminant et la vraie différence tient à ce qu’un processus est plus lourd en mémoire qu’un thread.
Maintenant c’est un peu limité comme choix dans la mesure où certains modules apache ne sont de toute façon pas totalement thread safe. Du coup, prefork reste le passage obligé. L’exemple typique est mod_php, rien que cela.
Les vrais gains de performances sont donc obtenus en paramétrant correctement le MPM prefork :
1 2 3 4 5 6 7 8 9 10
<IfModule mpm_prefork_module> ... MaxClients 200 ServerLimit 100 StartServers 4 MinSpareServers 1 MaxSpareServers 8 MaxRequestsPerChild 1000 ... </IfModule>
paramétrage prefork
Tout commence avec MaxClients qui détermine le maximum de requêtes pouvant être servies en parralèle, et donc le nombre maximum de serveurs à lancer. Ici nous reprenons bêtement le réglage donnée pour le Keep-Alive, à 4 requêtes par utilisateur. MaxClients ne peut normalement pas dépasser 256 serveurs. Si vous avez besoin de plus, il faut spécifier une nouvelle borne max avec ServerLimit.
MinSpareServers et MaxSpareServers indiquent le nombre minimum et maximum de serveurs à conserver lorsqu’ils ne sont plus utilisés, y compris par le keep-alive. Il n’est donc pas nécessaire de mettre de grosses valeurs ici sauf pour un site à haute charge qui va chercher à économiser au maximum le temps de création des serveurs. J’ai tendance à prévoir 2 utilisateurs à 4 requêtes pour ce paramètres, soit 8 serveurs.
StartServers a un peu moins d’intérêt, il consiste en gros à préchauffer apache en lançant un certain nombre de serveurs au démarrage. Alors évidement si vous mettez 100 à StartServers et 8 à MaxSpareServers, vous allez perdre 92 serveurs quelques secondes après le lancement…
MaxRequestsPerChild est quant à elle la « faucheuse » du système. Lorsque le serveur n’est plus très frai, disons après 1000 requêtes servies, il est automatiquement tué.
Le cas FasterFox
FasterFox peut être décrit comme « a pain in the ass » comme disent nos amis outre-manche. Cette extension permet de faire deux choses magnifiques : pré-charger (ie prefetching) des choses en avance pour que vous les ayez en cache quant vous avez éventuellement envie d’aller les voir, augmenter le nombre de connexions concurrentes (ie pipelining) à des valeurs dépassant largement les préconisations des RFC (jusqu’à 8 en mode « turbo »). Résultat des courses, des utilisateurs bien peu civiques qui pourrissent la bande passante, souvent pour des prunes et vous explosent vos quotas de connexions simultanées.
Pour bloquer le prefetching la solution est très simple, il suffit d’ajouter dans votre robot.txt :
1 2
User-agent: Fasterfox Disallow: /
blockage du prefetching
En effet, FasterFox a malgré tout la courtoisie de vérifier ce fichier avant de faire son petit carnage.
Pour limiter le nombre de connexions par IP (aka pipelining) c’est un peu plus délicat et sûrement moins critique que le prefetching. En effet, comme le fait justement remarquer Daniel dans son commentaire, il n’est pas évident que 8 connexions pendant 1 secondes soient pires pour les camarades que 4 connexions pendant 2 secondes. De plus, autre remarque judicieuse du même auteur, limiter le nombre de connexions par IP, c’est prendre le risque de bloquer des utilisateurs légitimes derrières un Proxy ou plus banalement derrière un NAT.
Si vous tenez malgrès tout à mettre en oeuvre cette limitation, cela consiste à ajouter à votre apache le module mod_limitipcon qui comme son nom l’indique va limiter le nombre de connections allouées à une adresse IP à un moment T donné. Ce module dépend du module mod_status qu’il convient donc d’activer aussi.
1 2 3 4 5 6 7 8 9 10 11
<IfModule mod_status.c> ExtendedStatus On <IfModule mod_limitipconn.c> <Location /un/chemin/a/limiter> MaxConnPerIP 4 </Location> ErrorDocument 503 \ "Ce serait sympathique de ne pas dépasser 4 connections en parralèle, merci." </IfModule> </IfModule>
blockage du pipelining abusif
Conclusion
Il y a bien d’autres paramétrages sur lequel jouer pour obtenir les meilleurs performances, mais celles présentées ici sont de meilleur rapport qualité/prix. A noter qu’un mauvais réglage, surtout dans la partie MPM, peut sans aucun problème multiplier (ou diviser) par 4 le temps de chargement d’une page.
Source: artisan.karma-lab.net.