<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Documentations diverses

Optimisation des performances d'Apache

Langues Disponibles:  en  |  fr  |  ko  |  tr 

Apache 2.x est un serveur web � usage g�n�ral, con�u dans un but d'�quilibre entre souplesse, portabilit� et performances. Bien que non con�u dans le seul but d'�tablir une r�f�rence en la mati�re, Apache 2.x est capable de hautes performances dans de nombreuses situations du monde r�el.

Compar�e � Apache 1.3, la version 2.x comporte de nombreuses optimisations suppl�mentaires permettant d'am�liorer le d�bit du serveur et sa personnalisation. La plupart de ces am�liorations sont activ�es par d�faut. Cependant, certains choix de configuration � la compilation et � l'ex�cution peuvent affecter les performances de mani�re significative. Ce document d�crit les options qu'un administrateur de serveur peut configurer pour am�liorer les performances d'une installation d'Apache 2.x. Certaines de ces options de configuration permettent au d�mon httpd de mieux tirer parti des possibilit�s du mat�riel et du syst�me d'exploitation, tandis que d'autres permettent � l'administrateur de privil�gier la vitesse par rapport aux fonctionnalit�s.

top

Probl�mes mat�riels et relatifs au syst�me d'exploitation

Le principal probl�me mat�riel qui affecte les performances du serveur web est la m�moire vive (RAM). Un serveur web ne devrait jamais avoir � utiliser le swap, car le swapping augmente le temps de r�ponse de chaque requ�te au del� du point que les utilisateurs consid�rent comme "trop lent". Ceci incite les utilisateurs � cliquer sur "Stop", puis "Charger � nouveau", ce qui a pour effet d'augmenter encore la charge du serveur. Vous pouvez, et m�me devez d�finir la valeur de la directive MaxRequestWorkers de fa�on � ce que votre serveur ne lance pas un nombre de processus enfants tel qu'il commence � faire du swapping. La m�thode pour y parvenir est simple : d�terminez la taille de votre processus Apache standard en consultant votre liste de processus � l'aide d'un outil tel que top, et divisez votre quantit� totale de m�moire disponible par cette taille, tout en gardant un espace suffisant pour les autres processus.

Hormis ce r�glage relatif � la m�moire, le reste est trivial : le processeur, la carte r�seau et les disques doivent �tre suffisamment rapides, o� "suffisamment rapide" doit �tre d�termin� par l'exp�rience.

Le choix du syst�me d'exploitation d�pend principalement du contexte local. Voici cependant quelques conseils qui se sont g�n�ralement av�r�s utiles :

top

Optimisation de la configuration � l'ex�cution

HostnameLookups et autres consid�rations � propos du DNS

Avant Apache 1.3, la directive HostnameLookups �tait positionn�e par d�faut � On. Ce r�glage augmente le temps de r�ponse de chaque requ�te car il entra�ne une recherche DNS et le traitement de la requ�te ne pourra pas �tre achev� tant que cette recherche ne sera pas termin�e. Avec Apache 1.3, ce r�glage est d�fini par d�faut � Off. Si vous souhaitez que les adresses dans vos fichiers journaux soient r�solues en noms d'h�tes, utilisez le programme logresolve fourni avec Apache, ou un des nombreux paquets g�n�rateurs de rapports sur les journaux disponibles.

Il est recommand� d'effectuer ce genre de traitement a posteriori de vos fichiers journaux sur une autre machine que celle qui h�berge le serveur web en production, afin que cette activit� n'affecte pas les performances du serveur.

Si vous utilisez une directive Allowfrom domain ou Deny from domain (ce qui signifie que vous utilisez un nom d'h�te ou un nom de domaine � la place d'une adresse IP), vous devrez compter avec deux recherches DNS (une recherche inverse suivie d'une recherche directe pour s'assurer que l'adresse IP n'a pas �t� usurp�e). C'est pourquoi il est pr�f�rable, pour am�liorer les performances, d'utiliser des adresses IP plut�t que des noms lorsqu'on utilise ces directives, du moins chaque fois que c'est possible.

Notez qu'il est possible de modifier la port�e des directives, en les pla�ant par exemple � l'int�rieur d'une section <Location /server-status>. Les recherches DNS ne seront alors effectu�es que pour les requ�tes qui satisfont aux crit�res. Voici un exemple qui d�sactive les recherches DNS sauf pour les fichiers .html et .cgi :

HostnameLookups off
<Files ~ "\.(html|cgi)$">
  HostnameLookups on
</Files>
      

Mais m�me dans ce cas, si vous n'avez besoin de noms DNS que dans certains CGIs, vous pouvez effectuer l'appel � gethostbyname dans les CGIs sp�cifiques qui en ont besoin.

FollowSymLinks et SymLinksIfOwnerMatch

Chaque fois que la ligne Options FollowSymLinks sera absente, ou que la ligne Options SymLinksIfOwnerMatch sera pr�sente dans votre espace d'adressage, Apache devra effectuer des appels syst�me suppl�mentaires pour v�rifier la pr�sence de liens symboliques. Un appel suppl�mentaire par �l�ment du chemin du fichier. Par exemple, si vous avez :

DocumentRoot /www/htdocs
<Directory />
  Options SymLinksIfOwnerMatch
</Directory>
      

et si une requ�te demande l'URI /index.html, Apache effectuera un appel � lstat(2) pour /www, /www/htdocs, et /www/htdocs/index.html. Les r�sultats de ces appels � lstat ne sont jamais mis en cache, ils devront donc �tre g�n�r�s � nouveau pour chaque nouvelle requ�te. Si vous voulez absolument v�rifier la s�curit� des liens symboliques, vous pouvez utiliser une configuration du style :

DocumentRoot /www/htdocs
<Directory />
  Options FollowSymLinks
</Directory>

<Directory /www/htdocs>
  Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>
      

Ceci �vite au moins les v�rifications suppl�mentaires pour le chemin d�fini par DocumentRoot. Notez que vous devrez ajouter des sections similaires si vous avez des chemins d�finis par les directives Alias ou RewriteRule en dehors de la racine de vos documents. Pour am�liorer les performances, et supprimer toute protection des liens symboliques, ajoutez l'option FollowSymLinks partout, et n'utilisez jamais l'option SymLinksIfOwnerMatch.

AllowOverride

Dans toute partie de votre espace d'adressage o� vous autoriserez la surcharge de la configuration (en g�n�ral � l'aide de fichiers .htaccess), Apache va tenter d'ouvrir .htaccess pour chaque �l�ment du chemin du fichier demand�. Par exemple, si vous avez :

DocumentRoot /www/htdocs
<Directory />
  AllowOverride all
</Directory>
      

et qu'une requ�te demande l'URI /index.html, Apache tentera d'ouvrir /.htaccess, /www/.htaccess, et /www/htdocs/.htaccess. Les solutions sont similaires � celles �voqu�es pr�c�demment pour Options FollowSymLinks. Pour am�liorer les performances, utilisez AllowOverride None pour tous les niveaux de votre espace d'adressage.

N�gociation

Dans la mesure du possible, �vitez toute n�gociation de contenu si vous tenez au moindre gain en performances. En pratique toutefois, les b�n�fices de la n�gociation l'emportent souvent sur la diminution des performances. Il y a cependant un cas dans lequel vous pouvez acc�l�rer le serveur. Au lieu d'utiliser une directive g�n�rique comme :

DirectoryIndex index

utilisez une liste explicite d'options :

DirectoryIndex index.cgi index.pl index.shtml index.html

o� vous placez le choix courant en premi�re position.

Notez aussi que cr�er explicitement un fichier de correspondances de type fournit de meilleures performances que l'utilisation des MultiViews, car les informations n�cessaires peuvent �tre simplement obtenues en lisant ce fichier, sans avoir � parcourir le r�pertoire � la recherche de types de fichiers.

Par cons�quent, si la n�gociation de contenu est n�cessaire pour votre site, pr�f�rez les fichiers de correspondances de type aux directives Options MultiViews pour mener � bien cette n�gociation. Se r�f�rer au document sur la N�gociation de contenu pour une description compl�te des m�thodes de n�gociation, et les instructions permettant de cr�er des fichiers de correspondances de type.

Transfert en m�moire

Dans les situations o� Apache 2.x doit consulter le contenu d'un fichier en train d'�tre servi - par exemple � l'occasion du traitement d'une inclusion c�t� serveur - il transf�re en g�n�ral le fichier en m�moire si le syst�me d'exploitation supporte une forme quelconque de mmap(2).

Sur certains syst�mes, ce transfert en m�moire am�liore les performances. Dans certains cas, ce transfert peut toutefois les d�grader et m�me diminuer la stabilit� du d�mon httpd :

Pour les installations o� une de ces situations peut se produire, vous devez utiliser EnableMMAP off afin de d�sactiver le transfert en m�moire des fichiers servis. (Note : il est possible de passer outre cette directive au niveau de chaque r�pertoire.)

Sendfile

Dans les cas o� Apache peut se permettre d'ignorer le contenu du fichier � servir - par exemple, lorsqu'il sert un contenu de fichier statique - il utilise en g�n�ral le support sendfile du noyau si le syst�me d'exploitation supporte l'op�ration sendfile(2).

Sur la plupart des plateformes, l'utilisation de sendfile am�liore les performances en �liminant les m�canismes de lecture et envoi s�par�s. Dans certains cas cependant, l'utilisation de sendfile peut nuire � la stabilit� du d�mon httpd :

Pour les installations o� une de ces situations peut se produire, vous devez utiliser EnableSendfile off afin de d�sactiver la mise � disposition de contenus de fichiers par sendfile. (Note : il est possible de passer outre cette directive au niveau de chaque r�pertoire.)

Process Creation

Avant Apache 1.3, les directives MinSpareServers, MaxSpareServers, et StartServers avaient des effets drastiques sur les performances de r�f�rence. En particulier, Apache avait besoin d'un d�lai de "mont�e en puissance" afin d'atteindre un nombre de processus enfants suffisant pour supporter la charge qui lui �tait appliqu�e. Apr�s le lancement initial des processus enfants par StartServers, seulement un processus enfant par seconde �tait cr�� afin d'atteindre la valeur de la directive MinSpareServers. Ainsi, un serveur acc�d� par 100 clients simultan�s et utilisant la valeur par d�faut de 5 pour la directive StartServers, n�cessitait environ 95 secondes pour lancer suffisamment de processus enfants permettant de faire face � la charge. Ceci fonctionne en pratique pour les serveurs en production, car ils sont rarement red�marr�s. Ce n'est cependant pas le cas pour les tests de r�f�rence (benchmarks) o� le serveur ne fonctionne que 10 minutes.

La r�gle "un processus par seconde" avait �t� impl�ment�e afin d'�viter l'enlisement de la machine dans le d�marrage de nouveaux processus enfants. Pendant que la machine est occup�e � lancer des processus enfants, elle ne peut pas traiter les requ�tes. Mais cette r�gle impactait tellement la perception des performances d'Apache qu'elle a d� �tre remplac�e. A partir d'Apache 1.3, le code a assoupli la r�gle "un processus par seconde". Il va en lancer un, attendre une seconde, puis en lancer deux, attendre une seconde, puis en lancer quatre et ainsi de suite jusqu'� lancer 32 processus. Il s'arr�tera lorsque le nombre de processus aura atteint la valeur d�finie par la directive MinSpareServers.

Ceci s'av�re suffisamment r�actif pour pouvoir en g�n�ral se passer de manipuler les valeurs des directives MinSpareServers, MaxSpareServers et StartServers. Lorsque plus de 4 processus enfants sont lanc�s par seconde, un message est �mis vers le journal des erreurs. Si vous voyez appara�tre souvent ce genre de message, vous devez vous pencher sur ces r�glages. Pour vous guider, utilisez les informations d�livr�es par le module mod_status.

� mettre en relation avec la cr�ation de processus, leur destruction est d�finie par la valeur de la directive MaxConnectionsPerChild. Sa valeur par d�faut est 0, ce qui signifie qu'il n'y a pas de limite au nombre de connexions qu'un processus enfant peut traiter. Si votre configuration actuelle a cette directive r�gl�e � une valeur tr�s basse, de l'ordre de 30, il est conseill� de l'augmenter de mani�re significative. Si vous utilisez SunOs ou une ancienne version de Solaris, utilisez une valeur de l'ordre de 10000 � cause des fuites de m�moire.

Lorsqu'ils sont en mode "keep-alive", les processus enfants sont maintenus et ne font rien sinon attendre la prochaine requ�te sur la connexion d�j� ouverte. La valeur par d�faut de 5 de la directive KeepAliveTimeout tend � minimiser cet effet. Il faut trouver le bon compromis entre la bande passante r�seau et les ressources du serveur. En aucun cas vous ne devez choisir une valeur sup�rieure � 60 seconds, car la plupart des b�n�fices sont alors perdus.

top

Optimisation de la configuration � la compilation

Choisir un Module Multi-Processus (MPM)

Apache 2.x supporte les mod�les simultan�s enfichables, appel�s Modules Multi-Processus (MPMs). Vous devez choisir un MPM au moment de la construction d'Apache. Certaines plateformes ont des modules MPM sp�cifiques : mpm_netware, mpmt_os2 et mpm_winnt. Sur les syst�mes de type Unix, vous avez le choix entre un grand nombre de modules MPM. Le choix du MPM peut affecter la vitesse et l'�volutivit� du d�mon httpd :

Pour plus d'informations sur ces deux MPMs et les autres, veuillez vous r�f�rer � la documentation sur les MPM.

Modules

Comme le contr�le de l'utilisation de la m�moire est tr�s important en mati�re de performance, il est conseill� d'�liminer les modules que vous n'utilisez pas vraiment. Si vous avez construit ces modules en tant que DSOs, leur �limination consiste simplement � commenter la directive LoadModule associ�e � ce module. Ceci vous permet de v�rifier si votre site fonctionne toujours apr�s la suppression de tel ou tel module.

Par contre, si les modules que vous voulez supprimer sont li�s statiquement � votre binaire Apache, vous devrez recompiler ce dernier afin de pouvoir les �liminer.

La question qui d�coule de ce qui pr�c�de est �videmment de savoir de quels modules vous avez besoin et desquels vous pouvez vous passer. La r�ponse sera bien entendu diff�rente d'un site web � l'autre. Cependant, la liste minimale de modules n�cessaire � la survie de votre site contiendra certainement mod_mime, mod_dir et mod_log_config. mod_log_config est bien entendu optionnel puisque vous pouvez faire fonctionner un site web en se passant de fichiers journaux ; ceci est cependant d�conseill�.

Op�rations atomiques

Certains modules, � l'instar de mod_cache et des versions de d�veloppement r�centes du MPM worker, utilisent l'API atomique d'APR. Cette API propose des op�rations atomiques que l'on peut utiliser pour all�ger la synchronisation des threads.

Par d�faut, APR impl�mente ces op�rations en utilisant les m�canismes les plus efficaces disponibles sur chaque plateforme cible (Syst�me d'exploitation et processeur). De nombreux processeurs modernes, par exemple, poss�dent une instruction qui effectue une op�ration atomique de type comparaison et �change ou compare-and-swap (CAS) au niveau mat�riel. Sur certaines platesformes cependant, APR utilise par d�faut une impl�mentation de l'API atomique plus lente, bas�e sur les mutex, afin d'assurer la compatibilit� avec les anciens mod�les de processeurs qui ne poss�dent pas ce genre d'instruction. Si vous construisez Apache pour une de ces platesformes, et ne pr�voyez de l'ex�cuter que sur des processeurs r�cents, vous pouvez s�lectionner une impl�mentation atomique plus rapide � la compilation en utilisant l'option --enable-nonportable-atomics du script configure :

./buildconf
./configure --with-mpm=worker --enable-nonportable-atomics=yes

L'option --enable-nonportable-atomics concerne les platesformes suivantes :

Module mod_status et ExtendedStatus On

Si vous incluez le module mod_status � la construction d'Apache et ajoutez ExtendedStatus On � sa configuration, Apache va effectuer pour chaque requ�te deux appels � gettimeofday(2) (ou times(2) selon votre syst�me d'exploitation), et (pour les versions ant�rieures � 1.3) de nombreux appels suppl�mentaires � time(2). Tous ces appels sont effectu�s afin que le rapport de statut puisse contenir des indications temporelles. Pour am�liorer les performances, utilisez ExtendedStatus off (qui est le r�glage par d�faut).

accept Serialization - points de connexion � un programme (sockets) multiples

Mise en garde :

Cette section n'a pas �t� totalement mise � jour car elle ne tient pas compte des changements intervenus dans la version 2.x du Serveur HTTP Apache. Certaines informations sont encore pertinentes, il vous est cependant conseill� de les utiliser avec prudence.

Ce qui suit est une br�ve discussion � propos de l'API des sockets Unix. Supposons que votre serveur web utilise plusieurs directives Listen afin d'�couter plusieurs ports ou de multiples adresses. Afin de tester chaque socket pour voir s'il a une connexion en attente, Apache utilise select(2). select(2) indique si un socket a z�ro ou au moins une connexion en attente. Le mod�le d'Apache comporte plusieurs processus enfants, et tous ceux qui sont inactifs testent la pr�sence de nouvelles connexions au m�me moment. Une impl�mentation rudimentaire de ceci pourrait ressembler � l'exemple suivant (ces exemples ne sont pas extraits du code d'Apache, ils ne sont propos�s qu'� des fins p�dagogiques) :

        for (;;) {
          for (;;) {
            fd_set accept_fds;

            FD_ZERO (&accept_fds);
            for (i = first_socket; i <= last_socket; ++i) {
              FD_SET (i, &accept_fds);
            }
            rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
            if (rc < 1) continue;
            new_connection = -1;
            for (i = first_socket; i <= last_socket; ++i) {
              if (FD_ISSET (i, &accept_fds)) {
                new_connection = accept (i, NULL, NULL);
                if (new_connection != -1) break;
              }
            }
            if (new_connection != -1) break;
          }
          process_the(new_connection);
        }
      

Mais cette impl�mentation rudimentaire pr�sente une s�rieuse lacune. Rappelez-vous que les processus enfants ex�cutent cette boucle au m�me moment ; ils vont ainsi bloquer sur select s'ils se trouvent entre deux requ�tes. Tous ces processus bloqu�s vont se r�activer et sortir de select quand une requ�te va appara�tre sur un des sockets (le nombre de processus enfants qui se r�activent varie en fonction du syst�me d'exploitation et des r�glages de synchronisation). Ils vont alors tous entrer dans la boucle et tenter un "accept" de la connexion. Mais seulement un d'entre eux y parviendra (en supposant qu'il ne reste q'une seule connexion en attente), les autres vont se bloquer au niveau de accept. Ceci verrouille vraiment ces processus de telle sorte qu'ils ne peuvent plus servir de requ�tes que par cet unique socket, et il en sera ainsi jusqu'� ce que suffisamment de nouvelles requ�tes apparaissent sur ce socket pour les r�activer tous. Cette lacune a �t� document�e pour la premi�re fois dans PR#467. Il existe au moins deux solutions.

La premi�re consiste � rendre les sockets non blocants. Dans ce cas, accept ne bloquera pas les processus enfants, et ils pourront continuer � s'ex�cuter imm�diatement. Mais ceci consomme des ressources processeur. Supposons que vous ayez dix processus enfants inactifs dans select, et qu'une connexion arrive. Neuf des dix processus vont se r�activer, tenter un accept de la connexion, �chouer, et boucler dans select, tout en n'ayant finalement rien accompli. Pendant ce temps, aucun de ces processus ne traite les requ�tes qui arrivent sur d'autres sockets jusqu'� ce qu'ils retournent dans select. Finalement, cette solution ne semble pas tr�s efficace, � moins que vous ne disposiez d'autant de processeurs inactifs (dans un serveur multiprocesseur) que de processus enfants inactifs, ce qui n'est pas une situation tr�s courante.

Une autre solution, celle qu'utilise Apache, consiste � s�rialiser les entr�es dans la boucle interne. La boucle ressemble � ceci (les diff�rences sont mises en surbrillance) :

        for (;;) {
          accept_mutex_on ();
          for (;;) {
            fd_set accept_fds;
            
            FD_ZERO (&accept_fds);
            for (i = first_socket; i <= last_socket; ++i) {
              FD_SET (i, &accept_fds);
            }
            rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
            if (rc < 1) continue;
            new_connection = -1;
            for (i = first_socket; i <= last_socket; ++i) {
              if (FD_ISSET (i, &accept_fds)) {
                new_connection = accept (i, NULL, NULL);
                if (new_connection != -1) break;
              }
            }
            if (new_connection != -1) break;
          }
          accept_mutex_off ();
          process the new_connection;
        }
      

Les fonctions accept_mutex_on et accept_mutex_off impl�mentent un s�maphore permettant une exclusion mutuelle. Un seul processus enfant � la fois peut poss�der le mutex. Plusieurs choix se pr�sentent pour impl�menter ces mutex. Ce choix est d�fini dans src/conf.h (versions ant�rieures � 1.3) ou src/include/ap_config.h (versions 1.3 ou sup�rieures). Certaines architectures ne font pas ce choix du mode de verrouillage ; l'utilisation de directives Listen multiples sur ces architectures est donc peu s�r.

La directive Mutex permet de modifier l'impl�mentation du mutex mpm-accept � l'ex�cution. Des consid�rations sp�cifiques aux diff�rentes impl�mentations de mutex sont document�es avec cette directive.

Une autre solution qui a �t� imagin�e mais jamais impl�ment�e, consiste � s�rialiser partiellement la boucle -- c'est � dire y faire entrer un certain nombre de processus. Ceci ne pr�senterait un int�r�t que sur les machines multiprocesseurs o� plusieurs processus enfants peuvent s'ex�cuter simultan�ment, et encore, la s�rialisation ne tire pas vraiment parti de toute la bande passante. C'est une possibilit� d'investigation future, mais demeure de priorit� basse car les serveurs web � architecture hautement parall�le ne sont pas la norme.

Pour bien faire, vous devriez faire fonctionner votre serveur sans directives Listen multiples si vous visez les performances les plus �lev�es. Mais lisez ce qui suit.

accept Serialization - point de connexion � un programme (sockets) unique

Ce qui pr�c�de convient pour les serveurs � sockets multiples, mais qu'en est-il des serveurs � socket unique ? En th�orie, ils ne devraient pas rencontrer les m�mes probl�mes car tous les processus enfants peuvent se bloquer dans accept(2) jusqu'� ce qu'une connexion arrive, et ils ne sont pas utilis�s � ne rien faire. En pratique, ceci dissimule un m�me comportement de bouclage discut� plus haut dans la solution non-blocante. De la mani�re dont sont impl�ment�es les piles TCP, le noyau r�active v�ritablement tous les processus bloqu�s dans accept quand une seule connexion arrive. Un de ces processus prend la connexion en compte et retourne dans l'espace utilisateur, les autres bouclant dans l'espace du noyau et se d�sactivant quand ils s'aper�oivent qu'il n'y a pas de connexion pour eux. Ce bouclage est invisible depuis le code de l'espace utilisateur, mais il est quand-m�me pr�sent. Ceci peut conduire � la m�me augmentation de charge � perte que la solution non blocante au cas des sockets multiples peut induire.

Pour cette raison, il appara�t que de nombreuses architectures se comportent plus "proprement" si on s�rialise m�me dans le cas d'une socket unique. Il s'agit en fait du comportement par d�faut dans la plupart des cas. Des exp�riences pouss�es sous Linux (noyau 2.0.30 sur un biprocesseur Pentium pro 166 avec 128 Mo de RAM) ont montr� que la s�rialisation d'une socket unique provoque une diminution inf�rieure � 3% du nombre de requ�tes par secondes par rapport au traitement non s�rialis�. Mais le traitement non s�rialis� des sockets uniques induit un temps de r�ponse suppl�mentaire de 100 ms pour chaque requ�te. Ce temps de r�ponse est probablement provoqu� par une limitation sur les lignes � haute charge, et ne constitue un probl�me que sur les r�seaux locaux. Si vous voulez vous passer de la s�rialisation des sockets uniques, vous pouvez d�finir SINGLE_LISTEN_UNSERIALIZED_ACCEPT et les serveurs � socket unique ne pratiqueront plus du tout la s�rialisation.

Fermeture en prenant son temps (Lingering close)

Comme discut� dans draft-ietf-http-connection-00.txt section 8, pour impl�menter de mani�re fiable le protocole, un serveur HTTP doit fermer les deux directions d'une communication ind�pendamment (rappelez-vous qu'une connexion TCP est bidirectionnelle, chaque direction �tant ind�pendante de l'autre).

Quand cette fonctionnalit� fut ajout�e � Apache, elle causa une avalanche de probl�mes sur plusieurs versions d'Unix � cause d'une impl�mentation � courte vue. La sp�cification TCP ne pr�cise pas que l'�tat FIN_WAIT_2 poss�de un temps de r�ponse mais elle ne l'exclut pas. Sur les syst�mes qui n'introduisent pas ce temps de r�ponse, Apache 1.2 induit de nombreux blocages d�finitifs de socket dans l'�tat FIN_WAIT_2. On peut eviter ceci dans de nombreux cas tout simplement en mettant � jour TCP/IP avec le dernier patch mis � disposition par le fournisseur. Dans les cas o� le fournisseur n'a jamais fourni de patch (par exemple, SunOS4 -- bien que les utilisateurs poss�dant une license source puissent le patcher eux-m�mes), nous avons d�cid� de d�sactiver cette fonctionnalit�.

Il y a deux m�thodes pour arriver � ce r�sultat. La premi�re est l'option de socket SO_LINGER. Mais le sort a voulu que cette solution ne soit jamais impl�ment�e correctement dans la plupart des piles TCP/IP. Et m�me dans les rares cas o� cette solution a �t� impl�ment�e correctement (par exemple Linux 2.0.31), elle se montre beaucoup plus gourmande (en temps processeur) que la solution suivante.

Pour la plus grande partie, Apache impl�mente cette solution � l'aide d'une fonction appel�e lingering_close (d�finie dans http_main.c). La fonction ressemble approximativement � ceci :

        void lingering_close (int s)
        {
          char junk_buffer[2048];
          
          /* shutdown the sending side */
          shutdown (s, 1);

          signal (SIGALRM, lingering_death);
          alarm (30);

          for (;;) {
            select (s for reading, 2 second timeout);
            if (error) break;
            if (s is ready for reading) {
              if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
                break;
              }
              /* just toss away whatever is here */
            }
          }
          
          close (s);
        }
      

Ceci ajoute naturellement un peu de charge � la fin d'une connexion, mais s'av�re n�cessaire pour une impl�mentation fiable. Comme HTTP/1.1 est de plus en plus pr�sent et que toutes les connexions sont persistentes, la charge sera amortie par la multiplicit� des requ�tes. Si vous voulez jouer avec le feu en d�sactivant cette fonctionnalit�, vous pouvez d�finir NO_LINGCLOSE, mais c'est fortement d�conseill�. En particulier, comme les connexions persistantes en pipeline de HTTP/1.1 commencent � �tre utilis�es, lingering_close devient une absolue n�cessit� (et les connexions en pipeline sont plus rapides ; vous avez donc tout int�r�t � les supporter).

Fichier tableau de bord (Scoreboard file)

Les processus parent et enfants d'Apache communiquent entre eux � l'aide d'un objet appel� "Tableau de bord" (Scoreboard). Id�alement, cet �change devrait s'effectuer en m�moire partag�e. Pour les syst�mes d'exploitation auxquels nous avons eu acc�s, ou pour lesquels nous avons obtenu des informations suffisamment d�taill�es pour effectuer un portage, cet �change est en g�n�ral impl�ment� en utilisant la m�moire partag�e. Pour les autres, on utilise par d�faut un fichier d'�change sur disque. Le fichier d'�change sur disque est non seulement lent, mais aussi peu fiable (et propose moins de fonctionnalit�s). Recherchez dans le fichier src/main/conf.h correspondant � votre architecture soit USE_MMAP_SCOREBOARD, soit USE_SHMGET_SCOREBOARD. La d�finition de l'un des deux (ainsi que leurs compagnons respectifs HAVE_MMAP et HAVE_SHMGET), active le code fourni pour la m�moire partag�e. Si votre syst�me propose une autre solution pour la gestion de la m�moire partag�e, �ditez le fichier src/main/http_main.c et ajoutez la portion de code n�cessaire pour pouvoir l'utiliser dans Apache (Merci de nous envoyer aussi le patch correspondant).

Note � caract�re historique : le portage d'Apache sous Linux n'utilisait pas la m�moire partag�e avant la version 1.2. Ceci entra�nait un comportement tr�s rudimentaire et peu fiable des versions ant�rieures d'Apache sous Linux.

DYNAMIC_MODULE_LIMIT

Si vous n'avez pas l'intention d'utiliser les modules charg�s dynamiquement (ce qui est probablement le cas si vous �tes en train de lire ce document afin de personnaliser votre serveur en recherchant le moindre des gains en performances), vous pouvez ajouter la d�finition -DDYNAMIC_MODULE_LIMIT=0 � la construction de votre serveur. Ceci aura pour effet de lib�rer la m�moire RAM allou�e pour le chargement dynamique des modules.

top

Appendice : Analyse d�taill�e d'une trace

Voici la trace d'un appel syst�me d'Apache 2.0.38 avec le MPM worker sous Solaris 8. Cette trace a �t� collect�e � l'aide de la commande :

truss -l -p httpd_child_pid.

L'option -l demande � truss de tracer l'ID du LWP (lightweight process--la version de Solaris des threads niveau noyau) qui invoque chaque appel syst�me.

Les autres syst�mes peuvent proposer des utilitaires de tra�age des appels syst�me diff�rents comme strace, ktrace, ou par. Ils produisent cependant tous une trace similaire.

Dans cette trace, un client a demand� un fichier statique de 10 ko au d�mon httpd. Le tra�age des requ�tes pour des contenus non statiques ou comportant une n�gociation de contenu a une pr�sentation diff�rente (et m�me assez laide dans certains cas).

/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9

Dans cette trace, le thread � l'�coute s'ex�cute � l'int�rieur de LWP #67.

Notez l'absence de la s�rialisation d'accept(2). Sur cette plateforme sp�cifique, le MPM worker utilise un accept non s�rialis� par d�faut sauf s'il est en �coute sur des ports multiples.
/65:    lwp_park(0x00000000, 0)                         = 0
/67:    lwp_unpark(65, 1)                               = 0

Apr�s avoir accept� la connexion, le thread � l'�coute r�active un thread du worker pour effectuer le traitement de la requ�te. Dans cette trace, le thread du worker qui traite la requ�te est associ� � LWP #65.

/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0

Afin de pouvoir impl�menter les h�tes virtuels, Apache doit conna�tre l'adresse du socket local utilis� pour accepter la connexion. On pourrait supprimer cet appel dans de nombreuses situations (par exemple dans le cas o� il n'y a pas d'h�te virtuel ou dans le cas o� les directives Listen contiennent des adresses sans caract�res de substitution). Mais aucun effort n'a �t� accompli � ce jour pour effectuer ces optimisations.

/65:    brk(0x002170E8)                                 = 0
/65:    brk(0x002190E8)                                 = 0

L'appel brk(2) alloue de la m�moire dans le tas. Ceci est rarement visible dans une trace d'appel syst�me, car le d�mon httpd utilise des allocateurs m�moire de son cru (apr_pool et apr_bucket_alloc) pour la plupart des traitements de requ�tes. Dans cette trace, le d�mon httpd vient juste de d�marrer, et il doit appeler malloc(3) pour r�server les blocs de m�moire n�cessaires � la cr�ation de ses propres allocateurs de m�moire.

/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
/65:    fstat64(9, 0xFAF7B818)                          = 0
/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
/65:    fstat64(9, 0xFAF7B818)                          = 0
/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0

Ensuite, le thread de worker passe la connexion du client (descripteur de fichier 9) en mode non blocant. Les appels setsockopt(2) et getsockopt(2) constituent un effet de bord de la mani�re dont la libc de Solaris utilise fcntl(2) pour les sockets.

/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97

Le thread de worker lit la requ�te du client.

/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10

Ce d�mon httpd a �t� configur� avec les options Options FollowSymLinks et AllowOverride None. Il n'a donc ni besoin d'appeler lstat(2) pour chaque r�pertoire du chemin du fichier demand�, ni besoin de v�rifier la pr�sence de fichiers .htaccess. Il appelle simplement stat(2) pour v�rifier d'une part que le fichier existe, et d'autre part que c'est un fichier r�gulier, et non un r�pertoire.

/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269

Dans cet exemple, le d�mon httpd peut envoyer l'en-t�te de la r�ponse HTTP et le fichier demand� � l'aide d'un seul appel syst�me sendfilev(2). La s�mantique de sendfile varie en fonction des syst�mes d'exploitation. Sur certains autres syst�mes, il faut faire un appel � write(2) ou writev(2) pour envoyer les en-t�tes avant d'appeler sendfile(2).

/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78

Cet appel � write(2) enregistre la requ�te dans le journal des acc�s. Notez qu'une des choses manquant � cette trace est un appel � time(2). A la diff�rence d'Apache 1.3, Apache 2.x utilise gettimeofday(3) pour consulter l'heure. Sur certains syst�mes d'exploitation, comme Linux ou Solaris, gettimeofday est impl�ment� de mani�re optimis�e de telle sorte qu'il consomme moins de ressources qu'un appel syst�me habituel.

/65:    shutdown(9, 1, 1)                               = 0
/65:    poll(0xFAF7B980, 1, 2000)                       = 1
/65:    read(9, 0xFAF7BC20, 512)                        = 0
/65:    close(9)                                        = 0

Le thread de worker effectue une fermeture "en prenant son temps" (lingering close) de la connexion.

/65:    close(10)                                       = 0
/65:    lwp_park(0x00000000, 0)         (sleeping...)

Enfin, le thread de worker ferme le fichier qu'il vient de d�livrer et se bloque jusqu'� ce que le thread en �coute lui assigne une autre connexion.

/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)

Pendant ce temps, le thread � l'�coute peut accepter une autre connexion � partir du moment o� il a assign� la connexion pr�sente � un thread de worker (selon une certaine logique de contr�le de flux dans le MPM worker qui impose des limites au thread � l'�coute si tous les threads de worker sont occup�s). Bien que cela n'apparaisse pas dans cette trace, l'accept(2) suivant peut (et le fait en g�n�ral, en situation de charge �lev�e) s'ex�cuter en parall�le avec le traitement de la connexion qui vient d'�tre accept�e par le thread de worker.

Langues Disponibles:  en  |  fr  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our mailing lists.