Copyright © 2006 Vishnu Ram V
Copyright © 2006 Deny
Copyright © 2006 Joëlle Cornavin
Article paru dans le n°123 de la Gazette Linux de février 2006.
Traduction française par Deny
<deny CHEZ monaco POINT net>
.
Relecture de la traduction française par Joëlle Cornavin
<jcornavi CHEZ club TIRET internet POINT fr>
.
Article publié sous Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.
Apache, implémentation open source du serveur HTTP, est le serveur web le plus populaire sur l'Internet. L'enquête sur les serveurs web de décembre 2005 menée par Netcraft 1 montre qu'environ 70 % des sites sur Internet utilisent Apache.
Les performances du serveur Apache peuvent être améliorées en ajoutant des ressources matérielles complémentaires telles que de la mémoire vive, un processeur plus rapide, etc. Mais la plupart du temps, on peut obtenir le même résultat avec une configuration personnalisée du serveur. Cet article explique comment obtenir les performances maximales d'Apache avec les ressources matérielles existantes, en particulier sur des systèmes Linux. Naturellement, on part du principe qu'il y a assez de ressources matérielles — notamment assez de mémoire vive pour éviter que le serveur ne « swappe » fréquemment. Les deux premières sections présentent les diverses options de configuration compile-time
et run-time
. La section run-time suppose qu'Apache est compilé avec le MPM (Multi-Processing Module) prefork. La compression HTTP et la mise en cache (caching) est abordée plus loin. Pour finir, nous verrons l'utilisation de serveurs séparés pour la prise en charge de contenus statiques et dynamiques est abordée. Des connaissances de base sur la compilation et la configuration d'Apache et de Linux sont requises.
compile-time
Le serveur Apache HTTP est un programme modularisé dans lequel l'administrateur peut choisir les fonctions à inclure dans le serveur en sélectionnant un ensemble de modules 2. Les modules peuvent être compilés soit statiquement en tant qu'éléments du binaire HTTP, soit en tant qu'objets partagés dynamiques (DSO, Dynamic Shared Objects). Les modules DSO peuvent être compilés lors de la construction du serveur ou ajoutés ultérieurement via l'utilitaire apxs, ce qui permet une compilation à une date ultérieure. Le module mod_so doit être compilé statiquement dans le noyau d'Apache pour activer la prise en charge des DSO.
Exécutez Apache avec les seuls modules requis. Vous réduisez ainsi l'utilisation de la mémoire, ce qui améliore les performances du serveur. Les modules compilés statiquement économiseront la mémoire vive employée pour la prise en charge des modules chargés dynamiquement, mais vous devrez recompiler Apache pour ajouter ou supprimer un module. C'est ici que le mécanisme DSO prend tout son sens. Une fois que le module mod_so est compilé statiquement, n'importe quel autre module peut être ajouté ou supprimé à l'aide de la commande LoadModule dans le fichier httpd.conf. Naturellement, vous devrez compiler les modules à l'aide d'apxs s'ils ne l'ont pas été lors de la construction du serveur.
Le serveur Apache est livré avec une sélection de modules MPM qui sont chargés de lier les ports réseau sur la machine, en acceptant des requêtes et en répartissant les processus enfants pour traiter les requêtes 3. Un seul MPM peut être chargé à tout moment dans le serveur.
Le choix d'un MPM dépend de divers facteurs, selon que le système d'exploitation prend en charge ou non les fils d'exécution, la quantité de mémoire disponible, l'extensibilité par rapport à la stabilité, selon que des modules tiers avec des fils d'exécution non synchronisés sont utilisés ou non, etc.
Les systèmes Linux peuvent choisir d'employer un MPM avec fil d'exécution comme worker ou un MPM sans fil d'exécution comme prefork :
Le MPM worker emploie de multiples processus enfants. Il est multiprocessus à l'intérieur de chaque processus enfant, et chaque fil gère une seule connexion. Worker est rapide, hautement extensible et comparativement peu exigeant en mémoire. Il convient parfaitement pour des processeurs multiples. Par ailleurs, worker est moins tolérant aux modules défectueux, et un module défectueux peut affecter tous les fils d'un processus enfant.
Le MPM prefork emploie de multiples processus enfants, dont chacun gère une connexion à la fois. Prefork est bien adapté aux systèmes à un ou deux processeurs, la rapidité est comparable à celle de worker et il est hautement tolérant aux modules défectueux et aux « plantages » de processus enfants — mais il consomme beaucoup de mémoire. De plus, davantage de trafic entraîne une plus grande utilisation de mémoire.
run-time
La directive HostnameLookups
permet la recherche des DNS de façon à journaliser des noms d'hôtes plutôt que des adresses IP. Cette option ajoute un délai d'attente à chaque requête, puisque la recherche de DNS doit être réalisée avant que la requête soit terminée. HostnameLookups
est positionnée sur Off par défaut dans Apache 1.3 et supérieur. Laissez-le à Off et utilisez un programme de post-traitement tel que logresolve pour résoudre les adresses IP dans les fichiers journaux access d'Apache. Logresolve est livré avec Apache.
Lorsque vous faites appel aux directives Allow from
ou Deny from
, employez une adresse IP au lieu d'un nom de domaine ou d'un nom d'hôte. Autrement, une double recherche de DNS est effectuée pour s'assurer que le nom de domaine ou le nom d'hôte n'est pas usurpé.
AllowOverride
Si AllowOverride
n'est pas positionné sur None, alors Apache tentera d'ouvrir le fichier .htaccess (comme spécifié par la directive AccessFileName
) dans chaque répertoire qu'il visite. Par exemple :
DocumentRoot /var/www/html <Directory /> Options SymLinksIfOwnerMatch </Directory> |
Si une requête est effectuée pour l'URI ./index.html, alors Apache tentera d'ouvrir .htaccess, /var/.htaccess, /var/www/.htaccess et /var/www/html/.htaccess. Ces consultations supplémentaires du système de fichiers allongent le délai d'attente. Si .htaccess est exigé pour un répertoire particulier, alors adaptez-le pour ce seul répertoire.
FollowSymLinks
et SymLinksIfOwnerMatch
Si l'option FollowSymLinks
est cochée, alors le serveur suivra les liens symboliques dans ce répertoire. Si SymLinksIfOwnerMatch
est cochée, alors le serveur ne suivra les liens symboliques que si le fichier ou le répertoire cible appartient au même utilisateur que le lien.
Si SymLinksIfOwnerMatch
est cochée, alors Apache devra émettre des appels système supplémentaires pour vérifier si l'appartenance du lien correspond et du fichier cible correspondent. Des appels système supplémentaires sont également necessaires quand FollowSymLinks
n'est PAS cochée. Par exemple :
DocumentRoot /var/www/html <Directory /> Options SymLinksIfOwnerMatch </Directory> |
Pour une requête effectuée pour l'URI /index.html, Apache exécutera lstat()
sur /var, /var/www, /var/www/html et /var/www/html/index.html. Ces appels système supplémentaires allongeront le délai d'attente. Les résultats de lstat n'étant pas mis en cache, ils apparaitront lors de chaque requête.
Pour obtenir des performances maximales, cochez FollowSymLinks
partout et ne cochez jamais SymLinksIfOwnerMatch
. Ou sinon, si l'option SymLinksIfOwnerMatch
est exigée pour un répertoire, alors cochez-la pour ce seul répertoire.
Évitez la négociation de contenu pour obtenir une réponse rapide. Si la négociation de contenu est requise pour le site, utilisez des fichiers type-map
plutôt que la directive Options MultiViews
. Avec MultiViews
, Apache doit balayer le répertoire pour rechercher les fichiers, ce qui allonge le délai d'attente.
MaxClients
La directive MaxClients
fixe la limite maximale de requêtes simultanées que le serveur peut prendre en charge ; aucun processus enfant au-delà de ce nombre n'est engendré. Il ne devrait pas être défini à une valeur trop basse, sinon un nombre toujours croissant de connexions sont reportées dans la file d'attente et occasionnent finalement un dépassement du temps imparti, alors que les ressources du serveur restent inutilisées. Si vous lui donnez une valeur trop élevée, en revanche, le serveur commencera à « swapper », ce qui fera diminuer considérablement le temps de réponse. La valeur appropriée pour MaxClients
peut être calculée ainsi :
4 MaxClients
= Mémoire vive totale dédiée au serveur web / Taille maximale des processus enfants.
La taille des processus enfants destinés à prendre en charge des fichiers statiques est d'environ 2 à 3 Mo. Pour du contenu dynamique tel que PHP, elle peut être aux environs de 15 Mo. La colonne RSS dans ps -ylC httpd --sort:rss affiche l'utilisation de la mémoire physique non permutée par des processus Apache en kilooctets.
S'il y a plus d'utilisateurs simultanés que MaxClients
, les requêtes seront mises en file d'attente jusqu'à un nombre défini en fonction de la directive ListenBacklog. Augmentez ServerLimit
pour régler MaxClients
au-dessus de 256.
MinSpareServers
, MaxSpareServers
et StartServers
MaxSpareServers
et MinSpareServers
déterminent combien de processus enfants doivent rester actifs tout en attendant des requêtes. Si MinSpareServers
est réglé trop bas et qu'un grand nombre de demandes survient, Apache devra engendrer des processus enfants supplémentaires pour satisfaire les requêtes. Créer des processus enfants est relativement exigeant en mémoire. Si le serveur est occupé à créer des processus enfants, il ne sera pas en mesure de prendre en charge les requêtes des clients immédiatement. MaxSpareServers
ne devrait pas être réglé trop haut : trop de processus enfants consommeront des ressources inutilement.
Affinez MinSpareServers
et MaxSpareServers
de façon à ce qu'Apache n'ait pas à engendrer plus de 4 processus enfants par seconde (Apache peut engendrer un maximum de 32 processus enfants par seconde). Si plus de 4 processus enfants par seconde sont engendrés, un message est journalisé dans ErrorLog.
La directive StartServers
fixe le nombre de processus enfants que le serveur crée au démarrage. Apache continuera à créer des processus enfants jusqu'à ce que le paramètre MinSpareServers
soit atteint. Cela n'aura pas grand effet sur les performances si le serveur n'est pas redémarré fréquemment. S'il y a beaucoup de requêtes et qu'Apache est souvent redémarré, donnez à cette directive une valeur relativement élevée.
MaxRequestsPerChild
La directive MaxRequestsPerChild
fixe la limite du nombre de requêtes que gérera un seul processus enfant du serveur. Après les requêtes MaxRequestsPerChild
, le processus enfant mourra mais comme il est fixé à 0 par défaut, le processus enfant n'expirera jamais. Il est approprié de donner à cette directive une valeur de quelques milliers. Cela peut aider à empêcher des pertes de mémoire, puisque le processus meurt après avoir satisfait un certain nombre de requêtes. Ne fixez pas une valeur trop basse, car la création de nouveaux processus est exigeante en temps système.
KeepAlive
et KeepAliveTimeout
La directive KeepAlive
autorise l'envoi de requêtes multiples sur la même connexion TCP. C'est particulièrement utile pour la prise en charge de pages HTML comportant de nombreuses images. Si KeepAlive
est positionnée sur Off, alors une connexion TCP séparée doit être créée pour chacune des images. La surcharge causée par l'établissement des connexions TCP peut être éliminée en positionnant KeepAlive
sur On.
KeepAliveTimeout
détermine la durée d'attente de la prochaine requête. Donnez-lui une valeur basse, peut-être entre deux et cinq secondes. Si la valeur fixée est trop élevèe, les processus enfants sont immobilisés, attendant le client alors qu'ils peuvent être utilisés pour satisfaire de nouveaux clients.
La totalité des spécifications de la compression HTTP figure dans HTTP/1.1. Le serveur utilise la méthode d'encodage gzip ou deflate pour la charge utile de réponse avant qu'elle ne soit envoyée au client. Le client décompresse les données utiles. Il n'y a aucun besoin d'installer un logiciel supplémentaire côté client puisque tous les navigateurs majeurs prennent en charge ces méthodes. Utiliser la compression économisera de la bande passante et améliorera le temps de réponse. Des études ont relevé un gain moyen de 75,2 % grâce à la compression 5.
La compression HTTP peut être activée dans Apache à l'aide du module mod_deflate. La charge utile n'est compressée que si le navigateur demande la compression, sinon le contenu décompressé est pris en compte. Un navigateur prenant en charge la compression informe le serveur qu'il préfère du contenu compressé via l'en-tête de requête HTTP Accept-Encoding: gzip,deflate. Alors le serveur répond avec la charge utile compressée et l'en-tête de réponse positionnés sur Content-Encoding: gzip.
L'exemple suivant utilise telnet pour afficher la requête et les en-têtes de réponse :
bash-3.00$ telnet www.webperformance.org 80 Trying 24.60.234.27... Connected to www.webperformance.org (24.60.234.27). Escape character is '^]'. HEAD / HTTP/1.1 Host: www.webperformance.org Accept-Encoding: gzip,deflate HTTP/1.1 200 OK Date: Sat, 31 Dec 2005 02:29:22 GMT Server: Apache/2.0 X-Powered-By: PHP/5.1.1 Cache-Control: max-age=0 Expires: Sat, 31 Dec 2005 02:29:22 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 20 Content-Type: text/html; charset=ISO-8859-1 |
Lors de la mise en cache, une copie des données est stockée chez le client ou sur un serveur mandataire, de sorte que le serveur n'a pas à la rechercher fréquemment. Cela économisera de la bande passante, diminuera la charge sur le serveur et réduira le temps d'attente. Le contrôle du cache est effectué à l'aide d'en-têtes HTTP : Apache permet de le faire par le biais des modules mod_expires et mod_headers. On peut aussi utiliser la mise en cache côté serveur, dans laquelle le contenu le plus souvent affiché est stocké en mémoire, ce qui permet sa prise en charge rapide. Le module mod_cache peut servir à la mise en cache côté serveur ; il est stable en production dans la version 2.2. d'Apache.
Les processus d'Apache prenant en charge du contenu dynamique consomment de 3 Mo à 20 Mo de mémoire vive. La taille croît pour s'adapter au contenu pris en charge et elle ne décroît jamais jusqu'à ce que le processus meure. À titre d'exemple, supposons qu'un processus d'Apache croisse jusqu'à 20 Mo pendant le chargement de contenu dynamique. Une fois cette requête achevée, il est libre de satisfaire n'importe laquelle autre. Si une requête pour une image survient, alors ce processus de 20 Mo prend en charge du contenu statique, ce qu'un processus de 1 Mo pourrait tout aussi bien faire. Par conséquent, la mémoire est employée de façon inefficace.
Utilisez un Apache léger (avec un minimum de modules statiquement compilés) comme serveur frontal pour prendre en charge du contenu statique. Les requêtes concernant le contenu dynamique devraient être transférées au serveur Apache puissant (compilé avec tous les modules requis). Utiliser un serveur frontal léger offre l'avantage d'une prise en charge rapide du contenu statique sans pour autant consommer trop de mémoire, et seul le contenu dynamique est transféré vers le serveur complet.
Le transfert de requête peut être réalisé à l'aide des modules mod_proxy et mod_rewrite. Supposez qu'il y ait un serveur Apache léger qui écoute le port 80 et un Apache complet qui écoute le port 8088. Alors la configuration suivante dans le serveur Apache léger peut être employée pour transférer toutes les requêtes (sauf les requêtes pour les images) sur le serveur complet 9 :
ProxyPassReverse / http://%{HTTP_HOST}:8088/ RewriteEngine on RewriteCond %{REQUEST_URI} !.*\.(gif|png|jpg)$ RewriteRule ^/(.*) http://%{HTTP_HOST}:8088/$1 [P] |
Toutes les requêtes, sauf celles pour des images, seront transférées via le serveur mandataire au serveur dorsal. La réponse est reçue par le serveur frontal et fournie au client. En ce qui concerne le client, toutes les réponses semblent provenir d'un seul serveur.
Configurer Apache pour des performances maximales est complexe ; il n'y pas de règles ardues et rapides. Cela dépend beaucoup de la compréhension des exigences du serveur web et de l'expérimentation des diverses options disponibles. Faites appel à des outils comme ab et httperf pour mesurer les performances du serveur web. Des serveurs légers tels que tux ou thttpd peuvent aussi être utilisés comme serveur frontal. Si un serveur de base de données est employé, assurez-vous qu'il est optimisé de façon à ne pas créer de goulots d'étranglement. Dans le cas de MySQL, mtop permet de surveiller les requêtes lentes. Les performances des scripts PHP peuvent être ameliorées par le biais d'un produit de cache PHP tel que Turck MMCache. Il élimine la surcharge due à la compilation en mettant en cache les scripts PHP dans un état compilé.
http://www.xs4all.nl/~thomas/apachecon/PerformanceTuning.html
http://www.onlamp.com/pub/a/onlamp/2004/02/05/lamp_tuning.html
Administration Linux à 200 %, par Rob Flickenger
Je suis titulaire d'un MTech. (maîtrise) en Communication Systems (systèmes de communication) de l'IIT Madras (Institut Indien de Technologie de Madras). J'ai rejoint Poornam Info Vision Pvt Ltd. en 2003 et travaille pour Poornam depuis lors.
Mes centres d'intérêt sont l'optimisation de performances, la surveillance de serveurs et la sécurité. Pendant mon temps libre, je pratique le karaté, je lis et j'écoute de la musique.