httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gry...@apache.org
Subject svn commit: r742058 [2/2] - in /httpd/httpd/trunk/docs/manual/misc: index.html index.html.en index.html.fr index.xml.fr index.xml.meta perf-tuning.html perf-tuning.html.en perf-tuning.html.fr perf-tuning.xml.fr perf-tuning.xml.meta
Date Sun, 08 Feb 2009 11:21:22 GMT
Added: httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.fr
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.fr?rev=742058&view=auto
==============================================================================
--- httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.fr (added)
+++ httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.fr Sun Feb  8 11:21:21 2009
@@ -0,0 +1,1174 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
+<!-- English Revision : 740028 -->
+<!-- French translation : Lucien GENTIS -->
+<!-- Reviewed by : Vincent Deffontaines -->
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manualpage metafile="perf-tuning.xml.meta">
+  <parentdocument href="./">Documentations diverses</parentdocument>
+
+  <title>Optimisation des performances d'Apache</title>
+
+  <summary>
+
+    <p>Apache 2.x est un serveur web &agrave; usage g&eacute;n&eacute;ral, con&ccedil;u dans un but
+    d'&eacute;quilibre entre souplesse, portabilit&eacute; et performances. Bien que non
+    con&ccedil;u dans le seul but d'&eacute;tablir une r&eacute;f&eacute;rence en la mati&egrave;re,
+    Apache 2.x est capable de hautes performances dans de nombreuses situations
+    du monde r&eacute;el.</p>
+
+    <p>Compar&eacute;e &agrave; Apache 1.3, la version 2.x comporte de nombreuses
+    optimisations suppl&eacute;mentaires permettant d'am&eacute;liorer le d&eacute;bit du serveur
+    et sa personnalisation. La plupart de ces am&eacute;liorations sont activ&eacute;es par
+    d&eacute;faut. Cependant, certains choix de configuration &agrave; la compilation et &agrave;
+    l'ex&eacute;cution peuvent affecter les performances de mani&egrave;re significative. Ce
+    document d&eacute;crit les options qu'un administrateur de serveur peut configurer
+    pour am&eacute;liorer les performances d'une installation d'Apache 2.x. Certaines
+    de ces options de configuration permettent au d&eacute;mon httpd de mieux tirer
+    parti des possibilit&eacute;s du mat&eacute;riel et du syst&egrave;me d'exploitation, tandis
+    que d'autres permettent &agrave; l'administrateur de privil&eacute;gier la vitesse
+    par rapport aux fonctionnalit&eacute;s.</p>
+
+  </summary>
+
+  <section id="hardware">
+
+    <title>Probl&egrave;mes mat&eacute;riels et relatifs au syst&egrave;me d'exploitation</title>
+
+    <p>Le principal probl&egrave;me mat&eacute;riel qui affecte les performances du serveur
+    web est la m&eacute;moire vive (RAM). Un serveur web ne devrait jamais avoir &agrave;
+    utiliser le swap, car le swapping augmente le temps de r&eacute;ponse de chaque
+    requ&ecirc;te au del&agrave; du point que les utilisateurs consid&egrave;rent comme
+    "trop lent". Ceci incite les utilisateurs &agrave; cliquer sur "Stop", puis
+    "Charger &agrave; nouveau", ce qui a pour effet d'augmenter encore la charge
+    du serveur. Vous pouvez, et m&ecirc;me devez d&eacute;finir la valeur de la directive
+    <directive module="mpm_common">MaxClients</directive> de fa&ccedil;on &agrave; ce que
+    votre serveur ne lance pas un nombre de processus enfants tel qu'il
+    commence &agrave; faire du swapping. La m&eacute;thode pour y parvenir est
+    simple : d&eacute;terminez la taille de votre processus Apache standard en
+    consultant votre liste de processus &agrave; l'aide d'un outil tel que
+    <code>top</code>, et divisez votre quantit&eacute; totale de m&eacute;moire disponible
+    par cette taille, tout en gardant un espace suffisant
+    pour les autres processus.</p>
+
+    <p>Hormis ce r&eacute;glage relatif &agrave; la m&eacute;moire, le reste est trivial : le
+    processeur, la carte r&eacute;seau et les disques doivent &ecirc;tre suffisamment
+    rapides, o&ugrave; "suffisamment rapide" doit &ecirc;tre d&eacute;termin&eacute; par
+    l'exp&eacute;rience.</p>
+
+    <p>Le choix du syst&egrave;me d'exploitation d&eacute;pend principalement du
+    contexte local. Voici cependant quelques conseils qui se sont
+    g&eacute;n&eacute;ralement av&eacute;r&eacute;s utiles :</p>
+
+    <ul>
+      <li>
+        <p>Ex&eacute;cutez la derni&egrave;re version stable et le niveau de patches le
+	plus haut du syst&egrave;me d'exploitation que vous avez choisi. De nombreux
+	&eacute;diteurs de syst&egrave;mes d'exploitation ont am&eacute;lior&eacute; de mani&egrave;re
+	significative les performances de leurs piles TCP et de leurs
+	biblioth&egrave;ques de thread ces derni&egrave;res ann&eacute;es.</p>
+      </li>
+
+      <li>
+        <p>Si votre syst&egrave;me d'exploitation poss&egrave;de un appel syst&egrave;me
+	<code>sendfile(2)</code>, assurez-vous d'avoir install&eacute; la version
+	et/ou les patches n&eacute;cessaires &agrave; son activation. (Pour Linux, par
+	exemple, cela se traduit par Linux 2.4 ou plus. Pour les versions
+	anciennes de Solaris 8, vous pouvez &ecirc;tre amen&eacute; &agrave; appliquer un patch.)
+	Sur les syst&egrave;mes o&ugrave; il est disponible, <code>sendfile</code> permet
+	&agrave; Apache 2 de servir les contenus statiques plus rapidement, tout en
+	induisant une charge CPU inf&eacute;rieure.</p>
+      </li>
+    </ul>
+
+  </section>
+
+  <section id="runtime">
+
+    <title>Optimisation de la configuration &agrave; l'ex&eacute;cution</title>
+
+    <related>
+      <modulelist>
+        <module>mod_dir</module>
+        <module>mpm_common</module>
+        <module>mod_status</module>
+      </modulelist>
+      <directivelist>
+        <directive module="core">AllowOverride</directive>
+        <directive module="mod_dir">DirectoryIndex</directive>
+        <directive module="core">HostnameLookups</directive>
+        <directive module="core">EnableMMAP</directive>
+        <directive module="core">EnableSendfile</directive>
+        <directive module="core">KeepAliveTimeout</directive>
+        <directive module="prefork">MaxSpareServers</directive>
+        <directive module="prefork">MinSpareServers</directive>
+        <directive module="core">Options</directive>
+        <directive module="mpm_common">StartServers</directive>
+      </directivelist>
+    </related>
+
+    <section id="dns">
+
+      <title>HostnameLookups et autres consid&eacute;rations &agrave; propos du DNS</title>
+
+      <p>Avant Apache 1.3, la directive
+      <directive module="core">HostnameLookups</directive> &eacute;tait positionn&eacute;e
+      par d&eacute;faut &agrave; <code>On</code>. Ce r&eacute;glage augmente le temps de r&eacute;ponse de
+      chaque requ&ecirc;te car il entra&icirc;ne une recherche DNS et le traitement de la
+      requ&ecirc;te ne pourra pas &ecirc;tre achev&eacute; tant que cette recherche ne sera
+      pas termin&eacute;e. Avec Apache 1.3, ce r&eacute;glage est d&eacute;fini par d&eacute;faut &agrave;
+      <code>Off</code>. Si vous souhaitez que les adresses dans vos fichiers
+      journaux soient r&eacute;solues en noms d'h&ocirc;tes, utilisez le programme
+      <program>logresolve</program> fourni avec Apache, ou un des nombreux
+      paquets g&eacute;n&eacute;rateurs de rapports sur les journaux disponibles.</p>
+
+      <p>Il est recommand&eacute; d'effectuer ce genre de traitement a posteriori
+      de vos fichiers journaux sur une autre machine que celle qui h&eacute;berge le
+      serveur web en production, afin que cette activit&eacute; n'affecte pas les
+      performances du serveur.</p>
+
+      <p>Si vous utilisez une directive
+      <code><directive module="mod_access_compat">Allow</directive>from domain</code>
+      ou
+      <code><directive module="mod_access_compat">Deny</directive> from domain</code>
+      (ce qui signifie que vous utilisez un nom d'h&ocirc;te ou un nom de domaine &agrave;
+      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 &eacute;t&eacute; usurp&eacute;e). C'est pourquoi il est
+      pr&eacute;f&eacute;rable, pour am&eacute;liorer les performances, d'utiliser des adresses IP
+      plut&ocirc;t que des noms lorsqu'on utilise ces directives, du moins chaque
+      fois que c'est possible.</p>
+
+      <p>Notez qu'il est possible de modifier la port&eacute;e des directives, en les
+      pla&ccedil;ant par exemple &agrave; l'int&eacute;rieur d'une section
+      <code>&lt;Location /server-status&gt;</code>. Les recherches DNS ne
+      seront alors effectu&eacute;es que pour les requ&ecirc;tes qui satisfont aux crit&egrave;res.
+      Voici un exemple qui d&eacute;sactive les recherches DNS sauf pour les fichiers
+      <code>.html</code> et <code>.cgi</code> :</p>
+
+      <example>
+        HostnameLookups off<br />
+        &lt;Files ~ "\.(html|cgi)$"&gt;<br />
+        <indent>
+          HostnameLookups on<br />
+        </indent>
+        &lt;/Files&gt;
+      </example>
+
+      <p>Mais m&ecirc;me dans ce cas, si vous n'avez besoin de noms DNS que dans
+      certains CGIs, vous pouvez effectuer l'appel &agrave; <code>gethostbyname</code>
+      dans les CGIs sp&eacute;cifiques qui en ont besoin.</p>
+
+    </section>
+
+    <section id="symlinks">
+
+      <title>FollowSymLinks et SymLinksIfOwnerMatch</title>
+
+      <p>Chaque fois que la ligne <code>Options FollowSymLinks</code> sera
+      absente, ou que la ligne <code>Options SymLinksIfOwnerMatch</code> sera
+      pr&eacute;sente dans votre espace d'adressage, Apache devra effectuer des
+      appels syst&egrave;me suppl&eacute;mentaires pour v&eacute;rifier la pr&eacute;sence de liens
+      symboliques. Un appel suppl&eacute;mentaire par &eacute;l&eacute;ment du chemin du fichier.
+      Par exemple, si vous avez :</p>
+
+      <example>
+        DocumentRoot /www/htdocs<br />
+        &lt;Directory /&gt;<br />
+        <indent>
+          Options SymLinksIfOwnerMatch<br />
+        </indent>
+        &lt;/Directory&gt;
+      </example>
+
+      <p>et si une requ&ecirc;te demande l'URI <code>/index.html</code>, Apache
+      effectuera un appel &agrave; <code>lstat(2)</code> pour
+      <code>/www</code>, <code>/www/htdocs</code>, et
+      <code>/www/htdocs/index.html</code>. Les r&eacute;sultats de ces appels &agrave;
+      <code>lstat</code> ne sont jamais mis en cache, ils devront donc &ecirc;tre
+      g&eacute;n&eacute;r&eacute;s &agrave; nouveau pour chaque nouvelle requ&ecirc;te. Si vous voulez absolument
+      v&eacute;rifier la s&eacute;curit&eacute; des liens symboliques, vous pouvez utiliser une
+      configuration du style :</p>
+
+      <example>
+        DocumentRoot /www/htdocs<br />
+        &lt;Directory /&gt;<br />
+        <indent>
+          Options FollowSymLinks<br />
+        </indent>
+        &lt;/Directory&gt;<br />
+        <br />
+        &lt;Directory /www/htdocs&gt;<br />
+        <indent>
+          Options -FollowSymLinks +SymLinksIfOwnerMatch<br />
+        </indent>
+        &lt;/Directory&gt;
+      </example>
+
+      <p>Ceci &eacute;vite au moins les v&eacute;rifications suppl&eacute;mentaires pour le chemin
+      d&eacute;fini par <directive module="core">DocumentRoot</directive>. Notez que
+      vous devrez ajouter des sections similaires si vous avez des chemins
+      d&eacute;finis par les directives
+      <directive module="mod_alias">Alias</directive> ou
+      <directive module="mod_rewrite">RewriteRule</directive> en dehors de
+      la racine de vos documents. Pour am&eacute;liorer les performances, et supprimer
+      toute protection des liens symboliques, ajoutez l'option
+      <code>FollowSymLinks</code> partout, et n'utilisez jamais l'option
+      <code>SymLinksIfOwnerMatch</code>.</p>
+
+    </section>
+
+    <section id="htacess">
+
+      <title>AllowOverride</title>
+
+      <p>Dans toute partie de votre espace d'adressage o&ugrave; vous autoriserez
+      la surcharge de la configuration (en g&eacute;n&eacute;ral &agrave; l'aide de fichiers
+      <code>.htaccess</code>), Apache va tenter d'ouvrir <code>.htaccess</code>
+      pour chaque &eacute;l&eacute;ment du chemin du fichier demand&eacute;. Par exemple, si vous
+      avez : </p>
+
+      <example>
+        DocumentRoot /www/htdocs<br />
+        &lt;Directory /&gt;<br />
+        <indent>
+          AllowOverride all<br />
+        </indent>
+        &lt;/Directory&gt;
+      </example>
+
+      <p>et qu'une requ&ecirc;te demande l'URI <code>/index.html</code>, Apache
+      tentera d'ouvrir <code>/.htaccess</code>, <code>/www/.htaccess</code>,
+      et <code>/www/htdocs/.htaccess</code>. Les solutions sont similaires &agrave;
+      celles &eacute;voqu&eacute;es pr&eacute;c&eacute;demment pour <code>Options FollowSymLinks</code>.
+      Pour am&eacute;liorer les performances, utilisez <code>AllowOverride None</code>
+      pour tous les niveaux de votre espace d'adressage.</p>
+
+    </section>
+
+    <section id="negotiation">
+
+      <title>N&eacute;gociation</title>
+
+      <p>Dans la mesure du possible, &eacute;vitez toute n&eacute;gociation de contenu si
+      vous tenez au moindre gain en performances. En pratique toutefois,
+      les b&eacute;n&eacute;fices de la n&eacute;gociation l'emportent souvent sur la diminution
+      des performances.
+      Il y a cependant un cas dans lequel vous pouvez acc&eacute;l&eacute;rer le serveur.
+      Au lieu d'utiliser une directive g&eacute;n&eacute;rique comme :</p>
+
+      <example>
+        DirectoryIndex index
+      </example>
+
+      <p>utilisez une liste explicite d'options :</p>
+
+      <example>
+        DirectoryIndex index.cgi index.pl index.shtml index.html
+      </example>
+
+      <p>o&ugrave; vous placez le choix courant en premi&egrave;re position.</p>
+
+      <p>Notez aussi que cr&eacute;er explicitement un fichier de
+      <code>correspondances de type</code> fournit de meilleures performances
+      que l'utilisation des <code>MultiViews</code>, car les informations
+      n&eacute;cessaires peuvent &ecirc;tre simplement obtenues en lisant ce fichier, sans
+      avoir &agrave; parcourir le r&eacute;pertoire &agrave; la recherche de types de fichiers.</p>
+
+    <p>Par cons&eacute;quent, si la n&eacute;gociation de contenu est n&eacute;cessaire pour votre
+    site, pr&eacute;f&eacute;rez les fichiers de <code>correspondances de type</code> aux
+    directives <code>Options MultiViews</code> pour mener &agrave; bien cette
+    n&eacute;gociation. Se r&eacute;f&eacute;rer au document sur la
+    <a href="../content-negotiation.html">N&eacute;gociation de contenu</a> pour une
+    description compl&egrave;te des m&eacute;thodes de n&eacute;gociation, et les instructions
+    permettant de cr&eacute;er des fichiers de <code>correspondances de type</code>.</p>
+
+    </section>
+
+    <section>
+
+      <title>Transfert en m&eacute;moire</title>
+
+      <p>Dans les situations o&ugrave; Apache 2.x doit consulter le contenu d'un
+      fichier en train d'&ecirc;tre servi - par exemple &agrave; l'occasion du traitement
+      d'une inclusion c&ocirc;t&eacute; serveur - il transf&egrave;re en g&eacute;n&eacute;ral le fichier en
+      m&eacute;moire si le syst&egrave;me d'exploitation supporte une forme quelconque
+      de <code>mmap(2)</code>.</p>
+
+      <p>Sur certains syst&egrave;mes, ce transfert en m&eacute;moire am&eacute;liore les
+      performances. Dans certains cas, ce transfert peut toutefois les d&eacute;grader
+      et m&ecirc;me diminuer la stabilit&eacute; du d&eacute;mon httpd :</p>
+
+      <ul>
+        <li>
+          <p>Dans certains syst&egrave;mes d'exploitation, <code>mmap</code> devient
+	  moins efficace que <code>read(2)</code> quand le nombre de
+	  processeurs augmente. Sur les serveurs multiprocesseurs sous Solaris,
+	  par exemple, Apache 2.x sert parfois les fichiers consult&eacute;s par le
+	  serveur plus rapidement quand <code>mmap</code> est d&eacute;sactiv&eacute;.</p>
+        </li>
+
+        <li>
+          <p>Si vous transf&eacute;rez en m&eacute;moire un fichier localis&eacute; dans un syst&egrave;me
+	  de fichiers mont&eacute; par NFS, et si un processus sur
+	  une autre machine cliente NFS supprime ou tronque le fichier, votre
+	  processus peut rencontrer une erreur de bus la prochaine fois qu'il
+	  essaiera d'acc&eacute;der au contenu du fichier en m&eacute;moire.</p>
+        </li>
+      </ul>
+
+      <p>Pour les installations o&ugrave; une de ces situations peut se produire,
+      vous devez utiliser <code>EnableMMAP off</code> afin de d&eacute;sactiver le
+      transfert en m&eacute;moire des fichiers servis. (Note : il est possible de
+      passer outre cette directive au niveau de chaque r&eacute;pertoire.)</p>
+
+    </section>
+
+    <section>
+
+      <title>Sendfile</title>
+
+      <p>Dans les cas o&ugrave; Apache peut se permettre d'ignorer le contenu du
+      fichier &agrave; servir - par exemple, lorsqu'il sert un contenu de fichier
+      statique - il utilise en g&eacute;n&eacute;ral le support sendfile du noyau si le
+      syst&egrave;me d'exploitation supporte l'op&eacute;ration <code>sendfile(2)</code>.</p>
+
+      <p>Sur la plupart des plateformes, l'utilisation de sendfile am&eacute;liore
+      les performances en &eacute;liminant les m&eacute;canismes de lecture et envoi s&eacute;par&eacute;s.
+      Dans certains cas cependant, l'utilisation de sendfile peut nuire &agrave; la
+      stabilit&eacute; du d&eacute;mon httpd :</p>
+
+      <ul>
+        <li>
+          <p>Certaines plateformes peuvent pr&eacute;senter un support de sendfile
+	  d&eacute;faillant que la construction du syst&egrave;me n'a pas d&eacute;tect&eacute;, en
+	  particulier si les binaires ont &eacute;t&eacute; construits sur une autre machine
+	  et transf&eacute;r&eacute;s sur la machine o&ugrave; le support de sendfile est
+	  d&eacute;faillant.</p>
+        </li>
+        <li>
+          <p>Dans le cas des fichiers mont&eacute;s sous NFS, le noyau peut s'av&eacute;rer
+	  incapable de servir les fichiers r&eacute;seau de mani&egrave;re fiable depuis
+	  son propre cache.</p>
+        </li>
+      </ul>
+
+      <p>Pour les installations o&ugrave; une de ces situations peut se produire,
+      vous devez utiliser <code>EnableSendfile off</code> afin de d&eacute;sactiver
+      la mise &agrave; disposition de contenus de fichiers par sendfile. (Note : il
+      est possible de passer outre cette directive au niveau de chaque
+      r&eacute;pertoire.)</p>
+
+    </section>
+
+    <section id="process">
+
+      <title>Process Creation</title>
+
+      <p>Avant Apache 1.3, les directives
+      <directive module="prefork">MinSpareServers</directive>,
+      <directive module="prefork">MaxSpareServers</directive>, et
+      <directive module="mpm_common">StartServers</directive> avaient des
+      effets drastiques sur les performances de r&eacute;f&eacute;rence. En particulier,
+      Apache avait besoin d'un d&eacute;lai de "mont&eacute;e en puissance" afin d'atteindre
+      un nombre de processus enfants suffisant pour supporter la charge qui lui
+      &eacute;tait appliqu&eacute;e. Apr&egrave;s le lancement initial des processus enfants par
+      <directive module="mpm_common">StartServers</directive>, seulement un
+      processus enfant par seconde &eacute;tait cr&eacute;&eacute; afin d'atteindre la valeur de la
+      directive <directive module="prefork">MinSpareServers</directive>. Ainsi,
+      un serveur acc&eacute;d&eacute; par 100 clients simultan&eacute;s et utilisant la valeur par
+      d&eacute;faut de <code>5</code> pour la directive
+      <directive module="mpm_common">StartServers</directive>, n&eacute;cessitait
+      environ 95 secondes pour lancer suffisamment de processus enfants
+      permettant de faire face &agrave; la charge. Ceci fonctionne en pratique pour
+      les serveurs en production, car ils sont rarement red&eacute;marr&eacute;s. Ce n'est
+      cependant pas le cas pour les tests de r&eacute;f&eacute;rence (benchmarks) o&ugrave; le
+      serveur ne fonctionne que 10 minutes.</p>
+
+      <p>La r&egrave;gle "un processus par seconde" avait &eacute;t&eacute; impl&eacute;ment&eacute;e afin
+      d'&eacute;viter l'enlisement de la machine dans le d&eacute;marrage de nouveaux
+      processus enfants. Pendant que la machine est occup&eacute;e &agrave; lancer des
+      processus enfants, elle ne peut pas traiter les requ&ecirc;tes. Mais cette
+      r&egrave;gle impactait tellement la perception des performances d'Apache qu'elle
+      a d&ucirc; &ecirc;tre remplac&eacute;e. A partir d'Apache 1.3, le code a assoupli la r&egrave;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'&agrave; lancer 32 processus. Il s'arr&ecirc;tera lorsque le
+      nombre de processus aura atteint la valeur d&eacute;finie par la directive
+      <directive module="prefork">MinSpareServers</directive>.</p>
+
+      <p>Ceci s'av&egrave;re suffisamment r&eacute;actif pour pouvoir en g&eacute;n&eacute;ral se passer
+      de manipuler les valeurs des directives
+      <directive module="prefork">MinSpareServers</directive>,
+      <directive module="prefork">MaxSpareServers</directive> et
+      <directive module="mpm_common">StartServers</directive>. Lorsque plus de
+      4 processus enfants sont lanc&eacute;s par seconde, un message est &eacute;mis vers
+      le journal des erreurs. Si vous voyez appara&icirc;tre souvent ce genre de
+      message, vous devez vous pencher sur ces r&eacute;glages. Pour vous guider,
+      utilisez les informations d&eacute;livr&eacute;es par le module
+      <module>mod_status</module>.</p>
+
+    <p>&Agrave; mettre en relation avec la cr&eacute;ation de processus, leur destruction
+    est d&eacute;finie par la valeur de la directive
+    <directive module="mpm_common">MaxRequestsPerChild</directive>. Sa valeur
+    par d&eacute;faut est <code>0</code>, ce qui signifie qu'il n'y a pas de limite
+    au nombre de requ&ecirc;tes q'un processus enfant peut traiter. Si votre
+    configuration actuelle a cette directive r&eacute;gl&eacute;e &agrave; une valeur tr&egrave;s basse,
+    de l'ordre de <code>30</code>, il est conseill&eacute; de l'augmenter de mani&egrave;re
+    significative. Si vous utilisez SunOs ou une ancienne version de Solaris,
+    utilisez une valeur de l'ordre de <code>10000</code>  &agrave; cause des fuites
+    de m&eacute;moire.</p>
+
+    <p>Lorsqu'ils sont en mode "keep-alive", les processus enfants sont
+    maintenus et ne font rien sinon attendre la prochaine requ&ecirc;te sur la
+    connexion d&eacute;j&agrave; ouverte. La valeur par d&eacute;faut de <code>5</code> de la
+    directive <directive module="core">KeepAliveTimeout</directive> tend &agrave;
+    minimiser cet effet. Il faut trouver le bon compromis entre la bande
+    passante r&eacute;seau et les ressources du serveur. En aucun cas vous ne devez
+    choisir une valeur sup&eacute;rieure &agrave; <code>60</code> seconds, car
+    <a href="http://www.research.digital.com/wrl/techreports/abstracts/95.4.html">
+    la plupart des b&eacute;n&eacute;fices sont alors perdus</a>.</p>
+
+    </section>
+
+  </section>
+
+  <section id="compiletime">
+
+    <title>Optimisation de la configuration &agrave; la compilation</title>
+
+    <section>
+
+      <title>Choisir un Module Multi-Processus (MPM)</title>
+
+      <p>Apache 2.x supporte les mod&egrave;les simultan&eacute;s enfichables, appel&eacute;s
+      <a href="../mpm.html">Modules Multi-Processus</a> (MPMs). Vous devez
+      choisir un MPM au moment de la construction d'Apache. Certaines
+      plateformes ont des modules MPM sp&eacute;cifiques : <module>beos</module>,
+      <module>mpm_netware</module>, <module>mpmt_os2</module>, et
+      <module>mpm_winnt</module>. Sur les syst&egrave;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'&eacute;volutivit&eacute; du d&eacute;mon httpd :</p>
+
+      <ul>
+
+        <li>Le MPM <module>worker</module> utilise plusieurs processus
+	enfants poss&eacute;dant chacun de nombreux threads. Chaque thread g&egrave;re une
+	seule connexion &agrave; la fois. Worker est en g&eacute;n&eacute;ral un bon choix pour les
+	serveurs pr&eacute;sentant un traffic important car il poss&egrave;de une empreinte
+	m&eacute;moire plus petite que le MPM prefork.</li>
+
+        <li>Le MPM <module>prefork</module> utilise plusieurs processus enfants
+	poss&eacute;dant chacun un seul thread. Chaque processus g&egrave;re une seule
+	connexion &agrave; la fois. Sur de nombreux syst&egrave;mes, prefork est comparable
+	en mati&egrave;re de vitesse &agrave; worker, mais il utilise plus de m&eacute;moire. De par
+	sa conception sans thread, prefork pr&eacute;sente des avantages par rapport &agrave;
+	worker dans certaines situations : il peut &ecirc;tre utilis&eacute; avec les
+	modules tiers qui ne supportent pas le threading, et son d&eacute;bogage est plus
+	ais&eacute; sur les platesformes pr&eacute;sentant un support du d&eacute;bogage des threads
+	rudimentaire.</li>
+
+      </ul>
+
+      <p>Pour plus d'informations sur ces deux MPMs et les autres, veuillez
+      vous r&eacute;f&eacute;rer &agrave; la <a href="../mpm.html">documentation sur les
+      MPM</a>.</p>
+
+    </section>
+
+    <section id="modules">
+
+        <title>Modules</title>
+
+        <p>Comme le contr&ocirc;le de l'utilisation de la m&eacute;moire est tr&egrave;s important
+	en mati&egrave;re de performance, il est conseill&eacute; d'&eacute;liminer les modules que
+	vous n'utilisez pas vraiment. Si vous avez construit ces modules en
+	tant que <a href="../dso.html">DSOs</a>, leur &eacute;limination consiste
+	simplement &agrave; commenter la directive
+	<directive module="mod_so">LoadModule</directive> associ&eacute;e &agrave; ce
+	module. Ceci vous permet de v&eacute;rifier si votre site fonctionne toujours
+	apr&egrave;s la suppression de tel ou tel module.</p>
+
+        <p>Par contre, si les modules que vous voulez supprimer sont li&eacute;s
+	statiquement &agrave; votre binaire Apache, vous devrez recompiler ce dernier
+	afin de pouvoir les &eacute;liminer.</p>
+
+        <p>La question qui d&eacute;coule de ce qui pr&eacute;c&egrave;de est &eacute;videmment de
+	savoir de quels modules vous avez besoin et desquels vous pouvez vous
+	passer. La r&eacute;ponse sera bien entendu diff&eacute;rente d'un site web &agrave;
+	l'autre. Cependant, la liste <em>minimale</em> de modules n&eacute;cessaire &agrave;
+	la survie de votre site contiendra certainement
+	<module>mod_mime</module>, <module>mod_dir</module> et
+	<module>mod_log_config</module>. <code>mod_log_config</code> est bien
+	entendu optionnel puisque vous pouvez faire fonctionner un site web
+	en se passant de fichiers journaux ; ceci est cependant
+	d&eacute;conseill&eacute;.</p>
+
+    </section>
+
+    <section>
+
+      <title>Op&eacute;rations atomiques</title>
+
+      <p>Certains modules, &agrave; l'instar de <module>mod_cache</module> et des
+      versions de d&eacute;veloppement r&eacute;centes du MPM worker, utilisent l'API
+      atomique d'APR. Cette API propose des op&eacute;rations atomiques que l'on
+      peut utiliser pour all&eacute;ger la synchronisation des threads.</p>
+
+      <p>Par d&eacute;faut, APR impl&eacute;mente ces op&eacute;rations en utilisant les
+      m&eacute;canismes les plus efficaces disponibles sur chaque plateforme cible
+      (Syst&egrave;me d'exploitation et processeur). De nombreux processeurs modernes,
+      par exemple, poss&egrave;dent une instruction qui effectue une op&eacute;ration
+      atomique de type comparaison et &eacute;change ou compare-and-swap (CAS) au
+      niveau mat&eacute;riel. Sur certaines platesformes cependant, APR utilise par
+      d&eacute;faut une impl&eacute;mentation de l'API atomique plus lente, bas&eacute;e sur les
+      mutex, afin d'assurer la compatibilit&eacute; avec les anciens mod&egrave;les de
+      processeurs qui ne poss&egrave;dent pas ce genre d'instruction. Si vous
+      construisez Apache pour une de ces platesformes, et ne pr&eacute;voyez de
+      l'ex&eacute;cuter que sur des processeurs r&eacute;cents, vous pouvez s&eacute;lectionner une
+      impl&eacute;mentation atomique plus rapide &agrave; la compilation en utilisant
+      l'option <code>--enable-nonportable-atomics</code> du
+      script configure :</p>
+
+      <example>
+        ./buildconf<br />
+        ./configure --with-mpm=worker --enable-nonportable-atomics=yes
+      </example>
+
+      <p>L'option <code>--enable-nonportable-atomics</code> concerne les
+      platesformes suivantes :</p>
+
+      <ul>
+
+        <li>Solaris sur SPARC<br />
+            Sur Solaris/SPARC, APR utilise par d&eacute;faut les op&eacute;rations
+	    atomiques bas&eacute;es sur les mutex. Cependant, si vous ajoutez l'option
+	    <code>--enable-nonportable-atomics</code> au script configure, APR
+	    g&eacute;n&egrave;re un code qui utilise le code op&eacute;ration SPARC v8plus pour des
+	    op&eacute;rations de compare-and-swap mat&eacute;riel plus rapides. Si vous
+	    utilisez cette option de configure avec Apache, les op&eacute;rations
+	    atomiques seront plus efficaces (permettant d'all&eacute;ger la charge du
+	    processeur et un plus haut niveau de simultan&eacute;it&eacute;), mais
+	    l'ex&eacute;cutable produit ne fonctionnera que sur les processeurs
+	    UltraSPARC.
+	</li>
+
+        <li>Linux sur x86<br />
+            Sous Linux, APR utilise par d&eacute;faut les op&eacute;rations atomiques bas&eacute;es
+	    sur les mutex. Cependant, si vous ajoutez l'option
+	    <code>--enable-nonportable-atomics</code> au script configure,
+	    APR g&eacute;n&eacute;rera un code qui utilise un code d'op&eacute;ration du 486
+	    pour des op&eacute;rations de compare-and-swap mat&eacute;riel plus rapides. Le
+	    code r&eacute;sultant est plus efficace en mati&egrave;re d'op&eacute;rations atomiques,
+	    mais l'ex&eacute;cutable produit ne fonctionnera que sur des processeurs
+	    486 et sup&eacute;rieurs (et non sur des 386).
+        </li>
+
+      </ul>
+
+    </section>
+
+    <section>
+
+      <title>Module mod_status et ExtendedStatus On</title>
+
+      <p>Si vous incluez le module <module>mod_status</module> &agrave; la
+      construction d'Apache et ajoutez <code>ExtendedStatus On</code> &agrave; sa
+      configuration, Apache va effectuer pour chaque requ&ecirc;te deux appels &agrave;
+      <code>gettimeofday(2)</code> (ou <code>times(2)</code> selon votre
+      syst&egrave;me d'exploitation), et (pour les versions ant&eacute;rieures &agrave; 1.3) de
+      nombreux appels suppl&eacute;mentaires &agrave; <code>time(2)</code>. Tous ces
+      appels sont effectu&eacute;s afin que le rapport de statut puisse contenir
+      des indications temporelles. Pour am&eacute;liorer les performances, utilisez
+      <code>ExtendedStatus off</code> (qui est le r&eacute;glage par d&eacute;faut).</p>
+
+    </section>
+
+    <section>
+
+      <title>accept Serialization - points de connexion &agrave; un programme (sockets) multiples</title>
+
+    <note type="warning"><title>Mise en garde :</title>
+      <p>Cette section n'a pas &eacute;t&eacute; totalement mise &agrave; 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&eacute; de les utiliser avec prudence.</p>
+    </note>
+
+      <p>Ce qui suit est une br&egrave;ve discussion &agrave; propos de l'API des sockets
+      Unix. Supposons que votre serveur web utilise plusieurs directives
+      <directive module="mpm_common">Listen</directive> afin d'&eacute;couter
+      plusieurs ports ou de multiples adresses. Afin de tester chaque socket
+      pour voir s'il a une connexion en attente, Apache utilise
+      <code>select(2)</code>. <code>select(2)</code> indique si un socket a
+      <em>z&eacute;ro</em> ou <em>au moins une</em> connexion en attente. Le mod&egrave;le
+      d'Apache comporte plusieurs processus enfants, et tous ceux qui sont
+      inactifs testent la pr&eacute;sence de nouvelles connexions au m&ecirc;me moment.
+      Une impl&eacute;mentation rudimentaire de ceci pourrait ressembler &agrave;
+      l'exemple suivant
+      (ces exemples ne sont pas extraits du code d'Apache, ils ne sont
+      propos&eacute;s qu'&agrave; des fins p&eacute;dagogiques) :</p>
+
+      <example>
+        for (;;) {<br />
+        <indent>
+          for (;;) {<br />
+          <indent>
+            fd_set accept_fds;<br />
+            <br />
+            FD_ZERO (&amp;accept_fds);<br />
+            for (i = first_socket; i &lt;= last_socket; ++i) {<br />
+            <indent>
+              FD_SET (i, &amp;accept_fds);<br />
+            </indent>
+            }<br />
+            rc = select (last_socket+1, &amp;accept_fds, NULL, NULL, NULL);<br />
+            if (rc &lt; 1) continue;<br />
+            new_connection = -1;<br />
+            for (i = first_socket; i &lt;= last_socket; ++i) {<br />
+            <indent>
+              if (FD_ISSET (i, &amp;accept_fds)) {<br />
+              <indent>
+                new_connection = accept (i, NULL, NULL);<br />
+                if (new_connection != -1) break;<br />
+              </indent>
+              }<br />
+            </indent>
+            }<br />
+            if (new_connection != -1) break;<br />
+          </indent>
+          }<br />
+          process the new_connection;<br />
+        </indent>
+        }
+      </example>
+
+      <p>Mais cette impl&eacute;mentation rudimentaire pr&eacute;sente une s&eacute;rieuse lacune.
+      Rappelez-vous que les processus enfants ex&eacute;cutent cette boucle au m&ecirc;me
+      moment ; ils vont ainsi bloquer sur <code>select</code> s'ils se trouvent
+      entre deux requ&ecirc;tes. Tous ces processus bloqu&eacute;s vont se r&eacute;activer et
+      sortir de <code>select</code> quand une requ&ecirc;te va appara&icirc;tre sur un des
+      sockets (le nombre de processus enfants qui se r&eacute;activent varie en
+      fonction du syst&egrave;me d'exploitation et des r&eacute;glages de synchronisation).
+      Ils vont alors tous entrer dans la boucle et tenter un
+      <code>"accept"</code> 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 <code>accept</code>.
+      Ceci verrouille vraiment ces processus de telle sorte qu'ils ne peuvent
+      plus servir de requ&ecirc;tes que par cet unique socket, et il en sera ainsi
+      jusqu'&agrave; ce que suffisamment de nouvelles requ&ecirc;tes apparaissent sur ce
+      socket pour les r&eacute;activer tous. Cette lacune a &eacute;t&eacute; document&eacute;e pour la
+      premi&egrave;re fois dans
+      <a href="http://bugs.apache.org/index/full/467">PR#467</a>. Il existe
+      au moins deux solutions.</p>
+
+      <p>La premi&egrave;re consiste &agrave; rendre les sockets non blocants. Dans ce cas,
+      <code>accept</code> ne bloquera pas les processus enfants, et ils
+      pourront continuer &agrave; s'ex&eacute;cuter imm&eacute;diatement. Mais ceci consomme des
+      ressources processeur. Supposons que vous ayez dix processus enfants
+      inactifs dans <code>select</code>, et qu'une connexion arrive.
+      Neuf des dix processus vont se r&eacute;activer, tenter un <code>accept</code>
+      de la connexion, &eacute;chouer, et boucler dans <code>select</code>, tout en
+      n'ayant finalement rien accompli. Pendant ce temps, aucun de ces processus
+      ne traite les requ&ecirc;tes qui arrivent sur d'autres sockets jusqu'&agrave; ce
+      qu'ils retournent dans <code>select</code>. Finalement, cette solution
+      ne semble pas tr&egrave;s efficace, &agrave; 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&egrave;s courante.</p>
+
+      <p>Une autre solution, celle qu'utilise Apache, consiste &agrave; s&eacute;rialiser les
+      entr&eacute;es dans la boucle interne. La boucle ressemble &agrave; ceci (les
+      diff&eacute;rences sont mises en surbrillance) :</p>
+
+      <example>
+        for (;;) {<br />
+        <indent>
+          <strong>accept_mutex_on ();</strong><br />
+          for (;;) {<br />
+          <indent>
+            fd_set accept_fds;<br />
+            <br />
+            FD_ZERO (&amp;accept_fds);<br />
+            for (i = first_socket; i &lt;= last_socket; ++i) {<br />
+            <indent>
+              FD_SET (i, &amp;accept_fds);<br />
+            </indent>
+            }<br />
+            rc = select (last_socket+1, &amp;accept_fds, NULL, NULL, NULL);<br />
+            if (rc &lt; 1) continue;<br />
+            new_connection = -1;<br />
+            for (i = first_socket; i &lt;= last_socket; ++i) {<br />
+            <indent>
+              if (FD_ISSET (i, &amp;accept_fds)) {<br />
+              <indent>
+                new_connection = accept (i, NULL, NULL);<br />
+                if (new_connection != -1) break;<br />
+              </indent>
+              }<br />
+            </indent>
+            }<br />
+            if (new_connection != -1) break;<br />
+          </indent>
+          }<br />
+          <strong>accept_mutex_off ();</strong><br />
+          process the new_connection;<br />
+        </indent>
+        }
+      </example>
+
+      <p><a id="serialize" name="serialize">Les fonctions</a>
+      <code>accept_mutex_on</code> et <code>accept_mutex_off</code>
+      impl&eacute;mentent un s&eacute;maphore permettant une exclusion mutuelle. Un seul
+      processus enfant &agrave; la fois peut poss&eacute;der le mutex. Plusieurs choix se
+      pr&eacute;sentent pour impl&eacute;menter ces mutex. Ce choix est d&eacute;fini dans
+      <code>src/conf.h</code> (versions ant&eacute;rieures &agrave; 1.3) ou
+      <code>src/include/ap_config.h</code> (versions 1.3 ou sup&eacute;rieures).
+      Certaines architectures ne font pas ce choix du mode de verrouillage ;
+      l'utilisation de directives
+      <directive module="mpm_common">Listen</directive> multiples sur ces
+      architectures est donc peu s&ucirc;r.</p>
+
+      <p>On peut utiliser la directive
+      <directive module="mpm_common">AcceptMutex</directive> pour modifier
+      l'impl&eacute;mentation du mutex s&eacute;lectionn&eacute;e &agrave; l'ex&eacute;cution.</p>
+
+      <dl>
+        <dt><code>AcceptMutex flock</code></dt>
+
+        <dd>
+          <p>Cette m&eacute;thode utilise l'appel syst&egrave;me <code>flock(2)</code> pour
+	  cr&eacute;er un fichier verrou (dont la localisation est d&eacute;finie par la
+	  directive <directive module="mpm_common">LockFile</directive>.</p>
+        </dd>
+
+        <dt><code>AcceptMutex fcntl</code></dt>
+
+        <dd>
+          <p>Cette m&eacute;thode utilise l'appel syst&egrave;me <code>fcntl(2)</code> pour
+	  cr&eacute;er un fichier verrou ((dont la localisation est d&eacute;finie par la
+	  directive <directive module="mpm_common">LockFile</directive>.</p>
+        </dd>
+
+        <dt><code>AcceptMutex sysvsem</code></dt>
+
+        <dd>
+          <p>(Versions 1.3 ou sup&eacute;rieures) Cette m&eacute;thode utilise les s&eacute;maphores
+	  style SysV pour impl&eacute;menter les mutex. Malheureusement, les
+	  s&eacute;maphores style SysV ont quelques effets de bord n&eacute;fastes. L'un
+	  d'entre eux est la possibilit&eacute; pour Apache de s'arr&ecirc;ter sans
+	  "faire le m&eacute;nage" dans les s&eacute;maphores (voir la page de manuel de
+	  <code>ipcs(8)</code>). Un autre effet de bord est introduit par
+	  l'API des s&eacute;maphores qui permet &agrave; tout CGI s'ex&eacute;cutant sous le m&ecirc;me
+	  uid que le serveur web d'effectuer une attaque par d&eacute;ni de service
+	  (c'est &agrave; dire <em>tous</em> les CGIs, &agrave; moins que vous n'utilisiez
+	  un programme comme <program>suexec</program> ou
+	  <code>cgiwrapper</code>). C'est pour cette raison que cette m&eacute;thode
+	  n'est utilis&eacute;e sur aucune architecture sauf IRIX (o&ugrave; les deux
+	  m&eacute;thodes pr&eacute;c&eacute;dentes consomment des ressources de mani&egrave;re prohibitive
+	  sur la plupart des machines IRIX).</p>
+        </dd>
+
+        <dt><code>AcceptMutex pthread</code></dt>
+
+        <dd>
+          <p>(versions 1.3 ou sup&eacute;rieures) Cette m&eacute;thode utilise les mutex
+	  POSIX et devrait fonctionner sur toute architecture impl&eacute;mentant
+	  de mani&egrave;re compl&egrave;te la sp&eacute;cification concernant les threads POSIX ;
+	  il semble cependant qu'elle ne fonctionne que sur Solaris (versions
+	  2.5 ou sup&eacute;rieures), et sous certaines configurations seulement. Si
+	  vous tentez l'exp&eacute;rience, votre serveur risque de se bloquer et de ne
+	  plus r&eacute;pondre &agrave; vos sollicitations. Par contre, les serveurs
+	  n'h&eacute;bergeant que du contenu statique devraient fonctionner
+	  correctement.</p>
+        </dd>
+
+        <dt><code>AcceptMutex posixsem</code></dt>
+
+        <dd>
+          <p>(Versions 2.0 ou sup&eacute;rieures) Cette m&eacute;thode utilise les s&eacute;maphores
+	  POSIX. L'appartenance du s&eacute;maphore n'est pas r&eacute;cup&eacute;r&eacute;e quand un
+	  thread du processus qui d&eacute;tient le mutex provoque une erreur de
+	  segmentation, ce qui a pour effet de bloquer le serveur.</p>
+        </dd>
+
+      </dl>
+
+      <p>Si votre syst&egrave;me propose une m&eacute;thode de s&eacute;rialisation diff&eacute;rente de
+      celles de la liste ci-dessus, il pourrait &ecirc;tre int&eacute;ressant d'ajouter &agrave;
+      APR le code correspondant.</p>
+
+      <p>Une autre solution qui a &eacute;t&eacute; imagin&eacute;e mais jamais impl&eacute;ment&eacute;e, consiste
+      &agrave; s&eacute;rialiser partiellement la boucle -- c'est &agrave; dire y faire entrer un
+      certain nombre de processus. Ceci ne pr&eacute;senterait un int&eacute;r&ecirc;t que sur les
+      machines multiprocesseurs o&ugrave; plusieurs processus enfants peuvent
+      s'ex&eacute;cuter simultan&eacute;ment, et encore, la s&eacute;rialisation ne tire pas
+      vraiment parti de toute la bande passante. C'est une possibilit&eacute;
+      d'investigation future, mais demeure de priorit&eacute; basse car les serveurs
+      web &agrave; architecture hautement parall&egrave;le ne sont pas la norme.</p>
+
+      <p>Pour bien faire, vous devriez faire fonctionner votre serveur sans
+      directives <directive module="mpm_common">Listen</directive> multiples
+      si vous visez les performances les plus &eacute;lev&eacute;es.
+      Mais lisez ce qui suit.</p>
+
+    </section>
+
+    <section>
+
+      <title>accept Serialization - point de connexion &agrave; un programme (sockets) unique</title>
+
+      <p>Ce qui pr&eacute;c&egrave;de convient pour les serveurs &agrave; sockets multiples, mais
+      qu'en est-il des serveurs &agrave; socket unique ? En th&eacute;orie, ils ne
+      devraient pas rencontrer les m&ecirc;mes probl&egrave;mes car tous les processus
+      enfants peuvent se bloquer dans <code>accept(2)</code> jusqu'&agrave; ce qu'une
+      connexion arrive, et ils ne sont pas utilis&eacute;s &agrave; ne rien faire. En
+      pratique, ceci dissimule un m&ecirc;me comportement de bouclage
+      discut&eacute; plus haut dans la solution non-blocante. De la mani&egrave;re dont
+      sont impl&eacute;ment&eacute;es les piles TCP, le noyau r&eacute;active v&eacute;ritablement tous les
+      processus bloqu&eacute;s dans <code>accept</code> 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&eacute;sactivant quand ils s'aper&ccedil;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&ecirc;me pr&eacute;sent. Ceci peut conduire &agrave; la
+      m&ecirc;me augmentation de charge &agrave; perte que la solution non blocante au cas
+      des sockets multiples peut induire.</p>
+
+      <p>Pour cette raison, il appara&icirc;t que de nombreuses architectures se
+      comportent plus "proprement" si on s&eacute;rialise m&ecirc;me dans le cas d'une socket
+      unique. Il s'agit en fait du comportement par d&eacute;faut dans la plupart des
+      cas. Des exp&eacute;riences pouss&eacute;es sous Linux (noyau 2.0.30 sur un
+      biprocesseur Pentium pro 166 avec 128 Mo de RAM) ont montr&eacute; que la
+      s&eacute;rialisation d'une socket unique provoque une diminution inf&eacute;rieure &agrave; 3%
+      du nombre de requ&ecirc;tes par secondes par rapport au traitement non
+      s&eacute;rialis&eacute;. Mais le traitement non s&eacute;rialis&eacute; des sockets uniques induit
+      un temps de r&eacute;ponse suppl&eacute;mentaire de 100 ms pour chaque requ&ecirc;te. Ce
+      temps de r&eacute;ponse est probablement provoqu&eacute; par une limitation sur les
+      lignes &agrave; haute charge, et ne constitue un probl&egrave;me que sur les r&eacute;seaux
+      locaux. Si vous voulez vous passer de la s&eacute;rialisation des sockets
+      uniques, vous pouvez d&eacute;finir
+      <code>SINGLE_LISTEN_UNSERIALIZED_ACCEPT</code> et les
+      serveurs &agrave; socket unique ne pratiqueront plus du tout la
+      s&eacute;rialisation.</p>
+
+    </section>
+
+    <section>
+
+      <title>Fermeture en prenant son temps (Lingering close)</title>
+
+      <p>Comme discut&eacute; dans <a
+      href="http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt">
+      draft-ietf-http-connection-00.txt</a> section 8, pour impl&eacute;menter de
+      mani&egrave;re <strong>fiable</strong> le protocole, un serveur HTTP doit fermer
+      les deux directions d'une communication ind&eacute;pendamment (rappelez-vous
+      qu'une connexion TCP est bidirectionnelle, chaque direction &eacute;tant
+      ind&eacute;pendante de l'autre). Ce fait, souvent ignor&eacute; par les autres
+      serveurs, est impl&eacute;ment&eacute; correctement dans Apache depuis la
+      version 1.2.</p>
+
+      <p>Quand cette fonctionnalit&eacute; fut ajout&eacute;e &agrave; Apache, elle causa une
+      avalanche de probl&egrave;mes sur plusieurs versions d'Unix &agrave; cause d'une
+      impl&eacute;mentation &agrave; courte vue. La sp&eacute;cification TCP ne pr&eacute;cise pas que
+      l'&eacute;tat <code>FIN_WAIT_2</code> poss&egrave;de un temps de r&eacute;ponse mais elle ne
+      l'exclut pas. Sur les syst&egrave;mes qui n'introduisent pas ce temps de
+      r&eacute;ponse, Apache 1.2 induit de nombreux blocages d&eacute;finitifs de socket
+      dans l'&eacute;tat <code>FIN_WAIT_2</code>. On peut eviter ceci dans de nombreux
+      cas tout simplement en mettant &agrave; jour TCP/IP avec le dernier patch mis &agrave;
+      disposition par le fournisseur. Dans les cas o&ugrave; le fournisseur n'a
+      jamais fourni de patch (par exemple, SunOS4 -- bien que les utilisateurs
+      poss&eacute;dant une license source puissent le patcher eux-m&ecirc;mes), nous avons
+      d&eacute;cid&eacute; de d&eacute;sactiver cette fonctionnalit&eacute;.</p>
+
+      <p>Il y a deux m&eacute;thodes pour arriver &agrave; ce r&eacute;sultat. La premi&egrave;re est
+      l'option de socket <code>SO_LINGER</code>. Mais le sort a voulu que cette
+      solution ne soit jamais impl&eacute;ment&eacute;e correctement dans la plupart des
+      piles TCP/IP. Et m&ecirc;me dans les rares cas o&ugrave; cette solution a &eacute;t&eacute;
+      impl&eacute;ment&eacute;e correctement (par exemple Linux 2.0.31), elle se
+      montre beaucoup plus gourmande (en temps processeur) que la solution
+      suivante.</p>
+
+      <p>Pour la plus grande partie, Apache impl&eacute;mente cette solution &agrave; l'aide
+      d'une fonction appel&eacute;e <code>lingering_close</code> (d&eacute;finie dans
+      <code>http_main.c</code>). La fonction ressemble approximativement &agrave;
+      ceci :</p>
+
+      <example>
+        void lingering_close (int s)<br />
+        {<br />
+        <indent>
+          char junk_buffer[2048];<br />
+          <br />
+          /* shutdown the sending side */<br />
+          shutdown (s, 1);<br />
+          <br />
+          signal (SIGALRM, lingering_death);<br />
+          alarm (30);<br />
+          <br />
+          for (;;) {<br />
+          <indent>
+            select (s for reading, 2 second timeout);<br />
+            if (error) break;<br />
+            if (s is ready for reading) {<br />
+            <indent>
+              if (read (s, junk_buffer, sizeof (junk_buffer)) &lt;= 0) {<br />
+              <indent>
+                break;<br />
+              </indent>
+              }<br />
+              /* just toss away whatever is here */<br />
+            </indent>
+            }<br />
+          </indent>
+          }<br />
+          <br />
+          close (s);<br />
+        </indent>
+        }
+      </example>
+
+      <p>Ceci ajoute naturellement un peu de charge &agrave; la fin d'une connexion,
+      mais s'av&egrave;re n&eacute;cessaire pour une impl&eacute;mentation fiable. Comme HTTP/1.1
+      est de plus en plus pr&eacute;sent et que toutes les connexions sont
+      persistentes, la charge sera amortie par la multiplicit&eacute; des requ&ecirc;tes.
+      Si vous voulez jouer avec le feu en d&eacute;sactivant cette fonctionnalit&eacute;,
+      vous pouvez d&eacute;finir <code>NO_LINGCLOSE</code>, mais c'est fortement
+      d&eacute;conseill&eacute;. En particulier, comme les connexions persistantes en
+      pipeline de HTTP/1.1 commencent &agrave; &ecirc;tre utilis&eacute;es,
+      <code>lingering_close</code> devient une absolue n&eacute;cessit&eacute; (et les
+      <a
+      href="http://www.w3.org/Protocols/HTTP/Performance/Pipeline.html">
+      connexions en pipeline sont plus rapides</a> ; vous avez donc tout
+      int&eacute;r&ecirc;t &agrave; les supporter).</p>
+
+    </section>
+
+    <section>
+
+      <title>Fichier tableau de bord (Scoreboard file)</title>
+
+      <p>Les processus parent et enfants d'Apache communiquent entre eux &agrave;
+      l'aide d'un objet appel&eacute; "Tableau de bord" (Scoreboard). Id&eacute;alement, cet
+      &eacute;change devrait s'effectuer en m&eacute;moire partag&eacute;e. Pour les syst&egrave;mes
+      d'exploitation auxquels nous avons eu acc&egrave;s, ou pour lesquels nous avons
+      obtenu des informations suffisamment d&eacute;taill&eacute;es pour effectuer un
+      portage, cet &eacute;change est en g&eacute;n&eacute;ral impl&eacute;ment&eacute; en utilisant la m&eacute;moire
+      partag&eacute;e. Pour les autres, on utilise par d&eacute;faut un fichier d'&eacute;change sur
+      disque. Le fichier d'&eacute;change sur disque est non seulement lent, mais
+      aussi peu fiable (et propose moins de fonctionnalit&eacute;s). Recherchez dans
+      le fichier <code>src/main/conf.h</code> correspondant &agrave; votre
+      architecture soit <code>USE_MMAP_SCOREBOARD</code>, soit
+      <code>USE_SHMGET_SCOREBOARD</code>. La d&eacute;finition de l'un des deux
+      (ainsi que leurs compagnons respectifs <code>HAVE_MMAP</code> et
+      <code>HAVE_SHMGET</code>), active le code fourni pour la m&eacute;moire
+      partag&eacute;e. Si votre syst&egrave;me propose une autre solution pour la gestion de
+      la m&eacute;moire partag&eacute;e, &eacute;ditez le fichier <code>src/main/http_main.c</code>
+      et ajoutez la portion de code n&eacute;cessaire pour pouvoir l'utiliser dans
+      Apache (Merci de nous envoyer aussi le patch correspondant).</p>
+
+      <note>Note &agrave; caract&egrave;re historique : le portage d'Apache sous Linux
+      n'utilisait pas la m&eacute;moire partag&eacute;e avant la version 1.2. Ceci entra&icirc;nait
+      un comportement tr&egrave;s rudimentaire et peu fiable des versions ant&eacute;rieures
+      d'Apache sous Linux.</note>
+
+    </section>
+
+    <section>
+
+      <title>DYNAMIC_MODULE_LIMIT</title>
+
+      <p>Si vous n'avez pas l'intention d'utiliser les modules charg&eacute;s
+      dynamiquement (ce qui est probablement le cas si vous &ecirc;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&eacute;finition
+      <code>-DDYNAMIC_MODULE_LIMIT=0</code> &agrave; la construction de votre serveur.
+      Ceci aura pour effet de lib&eacute;rer la m&eacute;moire RAM allou&eacute;e pour le
+      chargement dynamique des modules.</p>
+
+    </section>
+
+  </section>
+
+  <section id="trace">
+
+    <title>Appendice : Analyse d&eacute;taill&eacute;e d'une trace</title>
+
+    <p>Voici la trace d'un appel syst&egrave;me d'Apache 2.0.38 avec le MPM worker
+    sous Solaris 8. Cette trace a &eacute;t&eacute; collect&eacute;e &agrave; l'aide de la commande :</p>
+
+    <example>
+      truss -l -p <var>httpd_child_pid</var>.
+    </example>
+
+    <p>L'option <code>-l</code> demande &agrave; truss de tracer l'ID du LWP
+    (lightweight process--la version de Solaris des threads niveau noyau) qui
+    invoque chaque appel syst&egrave;me.</p>
+
+    <p>Les autres syst&egrave;mes peuvent proposer des utilitaires de tra&ccedil;age
+    des appels syst&egrave;me diff&eacute;rents comme <code>strace</code>,
+    <code>ktrace</code>, ou <code>par</code>. Ils produisent cependant tous une
+    trace similaire.</p>
+
+    <p>Dans cette trace, un client a demand&eacute; un fichier statique de 10 ko au
+    d&eacute;mon httpd. Le tra&ccedil;age des requ&ecirc;tes pour des contenus non statiques
+    ou comportant une n&eacute;gociation de contenu a une pr&eacute;sentation
+    diff&eacute;rente (et m&ecirc;me assez laide dans certains cas).</p>
+
+    <example>
+<pre>/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
+/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9</pre>
+    </example>
+
+    <p>Dans cette trace, le thread &agrave; l'&eacute;coute s'ex&eacute;cute &agrave; l'int&eacute;rieur de
+    LWP #67.</p>
+
+    <note>Notez l'absence de la s&eacute;rialisation d'<code>accept(2)</code>. Sur
+    cette plateforme sp&eacute;cifique, le MPM worker utilise un accept non s&eacute;rialis&eacute;
+    par d&eacute;faut sauf s'il est en &eacute;coute sur des ports multiples.</note>
+
+    <example>
+<pre>/65:    lwp_park(0x00000000, 0)                         = 0
+/67:    lwp_unpark(65, 1)                               = 0</pre>
+    </example>
+
+    <p>Apr&egrave;s avoir accept&eacute; la connexion, le thread &agrave; l'&eacute;coute r&eacute;active un
+    thread du worker pour effectuer le traitement de la requ&ecirc;te. Dans cette
+    trace, le thread du worker qui traite la requ&ecirc;te est associ&eacute; &agrave;
+    LWP #65.</p>
+
+    <example>
+<pre>/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0</pre>
+    </example>
+
+    <p>Afin de pouvoir impl&eacute;menter les h&ocirc;tes virtuels, Apache doit conna&icirc;tre
+    l'adresse du socket local utilis&eacute; pour accepter la connexion. On pourrait
+    supprimer cet appel dans de nombreuses situations (par exemple dans le cas
+    o&ugrave; il n'y a pas d'h&ocirc;te virtuel ou dans le cas o&ugrave; les directives
+    <directive module="mpm_common">Listen</directive> contiennent des adresses
+    sans caract&egrave;res de substitution). Mais aucun effort n'a &eacute;t&eacute; accompli &agrave; ce
+    jour pour effectuer ces optimisations.</p>
+
+    <example>
+<pre>/65:    brk(0x002170E8)                                 = 0
+/65:    brk(0x002190E8)                                 = 0</pre>
+    </example>
+
+    <p>L'appel <code>brk(2)</code> alloue de la m&eacute;moire dans le tas. Ceci est
+    rarement visible dans une trace d'appel syst&egrave;me, car le d&eacute;mon httpd
+    utilise des allocateurs m&eacute;moire de son cru (<code>apr_pool</code> et
+    <code>apr_bucket_alloc</code>) pour la plupart des traitements de requ&ecirc;tes.
+    Dans cette trace, le d&eacute;mon httpd vient juste de d&eacute;marrer, et il doit
+    appeler <code>malloc(3)</code> pour r&eacute;server les blocs de m&eacute;moire
+    n&eacute;cessaires &agrave; la cr&eacute;ation de ses propres allocateurs de m&eacute;moire.</p>
+
+    <example>
+<pre>/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</pre>
+    </example>
+
+    <p>Ensuite, le thread de worker passe la connexion du client (descripteur
+    de fichier 9) en mode non blocant. Les appels <code>setsockopt(2)</code>
+    et <code>getsockopt(2)</code> constituent un effet de bord de la mani&egrave;re
+    dont la libc de Solaris utilise <code>fcntl(2)</code> pour les sockets.</p>
+
+    <example>
+<pre>/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97</pre>
+    </example>
+
+    <p>Le thread de worker lit la requ&ecirc;te du client.</p>
+
+    <example>
+<pre>/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</pre>
+    </example>
+
+    <p>Ce d&eacute;mon httpd a &eacute;t&eacute; configur&eacute; avec les options
+    <code>Options FollowSymLinks</code> et <code>AllowOverride None</code>. Il
+    n'a donc ni besoin d'appeler <code>lstat(2)</code> pour chaque r&eacute;pertoire
+    du chemin du fichier demand&eacute;, ni besoin de v&eacute;rifier la pr&eacute;sence de fichiers
+    <code>.htaccess</code>. Il appelle simplement <code>stat(2)</code> pour
+    v&eacute;rifier d'une part que le fichier existe, et d'autre part que c'est un
+    fichier r&eacute;gulier, et non un r&eacute;pertoire.</p>
+
+    <example>
+<pre>/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269</pre>
+    </example>
+
+    <p>Dans cet exemple, le d&eacute;mon httpd peut envoyer l'en-t&ecirc;te de la r&eacute;ponse
+    HTTP et le fichier demand&eacute; &agrave; l'aide d'un seul appel syst&egrave;me
+    <code>sendfilev(2)</code>. La s&eacute;mantique de sendfile varie en fonction des
+    syst&egrave;mes d'exploitation. Sur certains autres syst&egrave;mes, il faut faire un
+    appel &agrave; <code>write(2)</code> ou <code>writev(2)</code> pour envoyer les
+    en-t&ecirc;tes avant d'appeler <code>sendfile(2)</code>.</p>
+
+    <example>
+<pre>/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78</pre>
+    </example>
+
+    <p>Cet appel &agrave; <code>write(2)</code> enregistre la requ&ecirc;te dans le journal
+    des acc&egrave;s. Notez qu'une des choses manquant &agrave; cette trace est un appel &agrave;
+    <code>time(2)</code>. A la diff&eacute;rence d'Apache 1.3, Apache 2.x utilise
+    <code>gettimeofday(3)</code> pour consulter l'heure. Sur certains syst&egrave;mes
+    d'exploitation, comme Linux ou Solaris, <code>gettimeofday</code> est
+    impl&eacute;ment&eacute; de mani&egrave;re optimis&eacute;e de telle sorte qu'il consomme moins de
+    ressources qu'un appel syst&egrave;me habituel.</p>
+
+    <example>
+<pre>/65:    shutdown(9, 1, 1)                               = 0
+/65:    poll(0xFAF7B980, 1, 2000)                       = 1
+/65:    read(9, 0xFAF7BC20, 512)                        = 0
+/65:    close(9)                                        = 0</pre>
+    </example>
+
+    <p>Le thread de worker effectue une fermeture "en prenant son temps"
+    (lingering close) de la connexion.</p>
+
+    <example>
+<pre>/65:    close(10)                                       = 0
+/65:    lwp_park(0x00000000, 0)         (sleeping...)</pre>
+    </example>
+
+    <p>Enfin, le thread de worker ferme le fichier qu'il vient de d&eacute;livrer et
+    se bloque jusqu'&agrave; ce que le thread en &eacute;coute lui assigne une autre
+    connexion.</p>
+
+    <example>
+<pre>/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)</pre>
+    </example>
+
+    <p>Pendant ce temps, le thread &agrave; l'&eacute;coute peut accepter une autre connexion
+    &agrave; partir du moment o&ugrave; il a assign&eacute; la connexion pr&eacute;sente &agrave; un thread de
+    worker (selon une certaine logique de contr&ocirc;le de flux dans le MPM worker
+    qui impose des limites au thread &agrave; l'&eacute;coute si tous les threads de worker
+    sont occup&eacute;s). Bien que cela n'apparaisse pas dans cette trace,
+    l'<code>accept(2)</code> suivant peut (et le fait en g&eacute;n&eacute;ral, en situation
+    de charge &eacute;lev&eacute;e) s'ex&eacute;cuter en parall&egrave;le avec le traitement de la
+    connexion qui vient d'&ecirc;tre accept&eacute;e par le thread de worker.</p>
+
+  </section>
+
+</manualpage>
+

Modified: httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.meta
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.meta?rev=742058&r1=742057&r2=742058&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.meta (original)
+++ httpd/httpd/trunk/docs/manual/misc/perf-tuning.xml.meta Sun Feb  8 11:21:21 2009
@@ -8,6 +8,7 @@
 
   <variants>
     <variant>en</variant>
+    <variant>fr</variant>
     <variant outdated="yes">ko</variant>
     <variant>tr</variant>
   </variants>



Mime
View raw message