mirror of
				https://github.com/apache/httpd.git
				synced 2025-11-03 17:53:20 +03:00 
			
		
		
		
	git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1874515 13f79535-47bb-0310-9956-ffa450edef68
		
			
				
	
	
		
			1645 lines
		
	
	
		
			82 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1645 lines
		
	
	
		
			82 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
<?xml version="1.0" encoding="utf-8"?>
 | 
						||
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
 | 
						||
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
 | 
						||
<!-- English Revision: 1874148 -->
 | 
						||
<!-- French translation : Lucien GENTIS -->
 | 
						||
 | 
						||
<!--
 | 
						||
 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-scaling.xml.meta"> 
 | 
						||
 | 
						||
    <parentdocument href="./">Documentations diverses</parentdocument>
 | 
						||
    
 | 
						||
    <title>Amélioration des performances</title>
 | 
						||
    
 | 
						||
    <summary>
 | 
						||
        
 | 
						||
        <p>Il est dit dans la documentation d'Apache 1.3
 | 
						||
	à propos de l'amélioration des performances : 
 | 
						||
        </p>
 | 
						||
        <blockquote><p>
 | 
						||
            "Apache est un serveur web à vocation générale, conçu pour
 | 
						||
	    être non seulement efficace mais aussi rapide. Dans sa
 | 
						||
	    configuration de base, ses performances sont déjà
 | 
						||
	    relativement satisfaisantes. La plupart des sites possèdent
 | 
						||
	    une bande passante en sortie inférieure à 10 Mbits que le
 | 
						||
	    serveur Apache peut mettre pleinement à profit en utilisant un serveur à base
 | 
						||
	    de processeur Pentium bas de gamme."</p>
 | 
						||
        </blockquote>
 | 
						||
        <p>Cette phrase ayant été écrite il y a plusieurs années,
 | 
						||
	entre temps de nombreuses choses ont changé. D'une part, les
 | 
						||
	serveurs sont devenus beaucoup plus rapides. D'autre part, de
 | 
						||
	nombreux sites se voient maintenant allouée une bande passante
 | 
						||
	en sortie bien supérieure à 10 Mbits. En outre, les applications
 | 
						||
	web sont devenues beaucoup plus complexes. Les sites classiques
 | 
						||
	ne proposant que des pages du style brochure sont toujours
 | 
						||
	présents, mais le web a souvent évolué vers une plateforme
 | 
						||
	exécutant des traitements, et les webmasters peuvent maintenant
 | 
						||
	mettre en ligne des contenus dynamiques en Perl, PHP ou Java,
 | 
						||
	qui exigent un niveau de performances bien supérieur. 
 | 
						||
        </p>
 | 
						||
        <p>C'est pourquoi en dépit des progrès en matière de bandes passantes
 | 
						||
	allouées et de rapidité	des serveurs, les performances
 | 
						||
	des serveurs web et des applications web sont toujours un sujet
 | 
						||
	d'actualité. C'est dans ce cadre que cette documentation s'attache à
 | 
						||
	présenter de nombreux points concernant les performances des
 | 
						||
	serveurs web. 
 | 
						||
        </p>
 | 
						||
        
 | 
						||
    </summary>
 | 
						||
    
 | 
						||
  <section id="what-will-and-will-not-be-discussed">
 | 
						||
        <title>Ce qui sera abordé et ce qui ne le sera pas</title>
 | 
						||
        <p>Ce document se concentre sur l'amélioration des performances
 | 
						||
	via des options facilement accessibles, ainsi que sur les outils
 | 
						||
	de monitoring. Les outils de monitoring vous permettront de
 | 
						||
	surveiller le fonctionnement de votre serveur web afin de
 | 
						||
	rassembler des informations à propos de ses performances et des
 | 
						||
	éventuels problèmes qui s'y rapportent. Nous supposerons
 | 
						||
	que votre budget n'est pas illimité ; c'est pourquoi les
 | 
						||
	améliorations apportées le seront sans modifier l'infrastructure
 | 
						||
	matérielle existante. Vous ne souhaitez probablement pas
 | 
						||
	compiler vous-même votre serveur Apache, ni recompiler le noyau
 | 
						||
	de votre système d'exploitation ; nous supposerons cependant que
 | 
						||
	vous possédez quelques notions à propos du fichier de
 | 
						||
	configuration du serveur HTTP Apache. 
 | 
						||
        </p>
 | 
						||
        
 | 
						||
    </section>
 | 
						||
    
 | 
						||
    <section id="monitoring-your-server">
 | 
						||
        <title>Monitoring de votre serveur</title>
 | 
						||
	<p>Si vous envisagez de redimensionner ou d'améliorer les performances
 | 
						||
	de votre serveur, vous devez tout d'abord observer la manière dont il
 | 
						||
	fonctionne. En observant son fonctionnement en conditions réelles ou
 | 
						||
	sous une charge créée artificiellement, vous serez en mesure
 | 
						||
	d'extrapoler son fonctionnement sous une charge accrue, par exemple dans
 | 
						||
	le cas où il serait mentionné sur Slashdot.  </p>
 | 
						||
        
 | 
						||
        
 | 
						||
        <section id="monitoring-tools">
 | 
						||
            <title>Outils de monitoring</title>
 | 
						||
            
 | 
						||
            <section id="top">
 | 
						||
                <title>top
 | 
						||
                </title>
 | 
						||
                <p>L'outil top est fourni avec Linux et FreeBSD. Solaris
 | 
						||
		quant à lui, fournit <code>prstat(1)</code>. Cet outil
 | 
						||
		permet de rassembler de nombreuses données statistiques
 | 
						||
		à propos du système et de chaque processus en cours
 | 
						||
		d'exécution avant de les afficher de manière
 | 
						||
		interactive sur votre terminal. Les données affichées
 | 
						||
		sont rafraîchies toutes les secondes et varient en
 | 
						||
		fonction de la plateforme, mais elles comportent en
 | 
						||
		général la charge moyenne du système, le nombre de
 | 
						||
		processus et leur état courant, le pourcentage de temps
 | 
						||
		CPU(s) passé à exécuter le code système et utilisateur,
 | 
						||
		et l'état de la mémoire virtuelle système. Les données
 | 
						||
		affichées pour chaque processus sont en général
 | 
						||
		configurables et comprennent le nom et l'identifiant du
 | 
						||
		processus, sa priorité et la valeur définie par nice,
 | 
						||
		l'empreinte mémoire, et le pourcentage d'utilisation CPU.
 | 
						||
		L'exemple suivant montre plusieurs processus httpd (avec
 | 
						||
		les MPM worker et event) s'exécutant sur un système
 | 
						||
		Linux (Xen) : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example><pre>
 | 
						||
top - 23:10:58 up 71 days,  6:14,  4 users,  load average: 0.25, 0.53, 0.47
 | 
						||
Tasks: 163 total,   1 running, 162 sleeping,   0 stopped,   0 zombie
 | 
						||
Cpu(s): 11.6%us,  0.7%sy,  0.0%ni, 87.3%id,  0.4%wa,  0.0%hi,  0.0%si,  0.0%st
 | 
						||
Mem:   2621656k total,  2178684k used,   442972k free,   100500k buffers
 | 
						||
Swap:  4194296k total,   860584k used,  3333712k free,  1157552k cached
 | 
						||
 | 
						||
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 | 
						||
16687 example_  20   0 1200m 547m 179m S   45 21.4   1:09.59 httpd-worker
 | 
						||
15195 www       20   0  441m  33m 2468 S    0  1.3   0:41.41 httpd-worker
 | 
						||
    1 root      20   0 10312  328  308 S    0  0.0   0:33.17 init
 | 
						||
    2 root      15  -5     0    0    0 S    0  0.0   0:00.00 kthreadd
 | 
						||
    3 root      RT  -5     0    0    0 S    0  0.0   0:00.14 migration/0
 | 
						||
    4 root      15  -5     0    0    0 S    0  0.0   0:04.58 ksoftirqd/0
 | 
						||
    5 root      RT  -5     0    0    0 S    0  0.0   4:45.89 watchdog/0
 | 
						||
    6 root      15  -5     0    0    0 S    0  0.0   1:42.52 events/0
 | 
						||
    7 root      15  -5     0    0    0 S    0  0.0   0:00.00 khelper
 | 
						||
   19 root      15  -5     0    0    0 S    0  0.0   0:00.00 xenwatch
 | 
						||
   20 root      15  -5     0    0    0 S    0  0.0   0:00.00 xenbus
 | 
						||
   28 root      RT  -5     0    0    0 S    0  0.0   0:00.14 migration/1
 | 
						||
   29 root      15  -5     0    0    0 S    0  0.0   0:00.20 ksoftirqd/1
 | 
						||
   30 root      RT  -5     0    0    0 S    0  0.0   0:05.96 watchdog/1
 | 
						||
   31 root      15  -5     0    0    0 S    0  0.0   1:18.35 events/1
 | 
						||
   32 root      RT  -5     0    0    0 S    0  0.0   0:00.08 migration/2
 | 
						||
   33 root      15  -5     0    0    0 S    0  0.0   0:00.18 ksoftirqd/2
 | 
						||
   34 root      RT  -5     0    0    0 S    0  0.0   0:06.00 watchdog/2
 | 
						||
   35 root      15  -5     0    0    0 S    0  0.0   1:08.39 events/2
 | 
						||
   36 root      RT  -5     0    0    0 S    0  0.0   0:00.10 migration/3
 | 
						||
   37 root      15  -5     0    0    0 S    0  0.0   0:00.16 ksoftirqd/3
 | 
						||
   38 root      RT  -5     0    0    0 S    0  0.0   0:06.08 watchdog/3
 | 
						||
   39 root      15  -5     0    0    0 S    0  0.0   1:22.81 events/3
 | 
						||
   68 root      15  -5     0    0    0 S    0  0.0   0:06.28 kblockd/0
 | 
						||
   69 root      15  -5     0    0    0 S    0  0.0   0:00.04 kblockd/1
 | 
						||
   70 root      15  -5     0    0    0 S    0  0.0   0:00.04 kblockd/2</pre></example>
 | 
						||
                
 | 
						||
                <p>Top est un merveilleux outil, même s'il est
 | 
						||
		relativement gourmand en ressources (lorsqu'il
 | 
						||
		s'exécute, son propre processus se trouve en général
 | 
						||
		dans le top dix des consommations CPU). Il est
 | 
						||
		indispensable pour déterminer la taille d'un processus
 | 
						||
		en cours d'exécution, information précieuse lorsque vous
 | 
						||
		voudrez déterminer combien de processus httpd vous
 | 
						||
		pourrez exécuter sur votre machine. La méthode pour
 | 
						||
		effectuer ce calcul est décrite ici : <a
 | 
						||
		href="#sizing-maxClients">calculer MaxClients</a>. Top
 | 
						||
		est cependant un outil interactif, et l'exécuter de
 | 
						||
		manière continu présente peu ou pas d'avantage. 
 | 
						||
                </p>
 | 
						||
            </section>
 | 
						||
            <section id="free">
 | 
						||
                <title>free
 | 
						||
                </title>
 | 
						||
                <p>Cette commande n'est disponible que sous Linux. Elle
 | 
						||
		indique la mémoire vive et l'espace de swap utilisés.
 | 
						||
		Linux alloue la mémoire inutilisée en tant que cache du
 | 
						||
		système de fichiers. La commande free montre
 | 
						||
		l'utilisation de la mémoire avec et sans ce cache. On
 | 
						||
		peut utiliser la commande free pour déterminer la
 | 
						||
		quantité de mémoire utilisée par le système, comme
 | 
						||
		décrit dans le paragraphe <a
 | 
						||
		href="#sizing-maxClients">calculer MaxClients</a>.
 | 
						||
		L'affichage de la sortie de la commande free ressemble à
 | 
						||
		ceci : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example><pre>
 | 
						||
sctemme@brutus:~$ free
 | 
						||
              total       used     free   shared    buffers    cached
 | 
						||
Mem:        4026028    3901892   124136         0    253144    841044
 | 
						||
-/+ buffers/cache:     2807704  1218324
 | 
						||
Swap:       3903784      12540  3891244
 | 
						||
                </pre></example>
 | 
						||
            </section>
 | 
						||
            
 | 
						||
            <section id="vmstat">
 | 
						||
                <title>vmstat
 | 
						||
                </title>
 | 
						||
                <p>Cette commande est disponible sur de nombreuses
 | 
						||
		plateformes de style Unix. Elle affiche un grand nombre
 | 
						||
		de données système. Lancée sans argument, elle affiche
 | 
						||
		une ligne d'état pour l'instant actuel. Lorsqu'on lui
 | 
						||
		ajoute un chiffre, la ligne d'état actuelle est ajoutée à
 | 
						||
		intervalles réguliers à l'affichage existant.
 | 
						||
		Par exemple, la commande
 | 
						||
		<code>vmstat 5</code> ajoute la ligne d'état actuelle
 | 
						||
		toutes les 5 secondes. La commande vmstat affiche la
 | 
						||
		quantité de mémoire virtuelle utilisée, la quantité de
 | 
						||
		mémoire échangée avec l'espace de swap en entrée et en
 | 
						||
		sortie à chaque seconde, le nombre de processus
 | 
						||
		actuellement en cours d'exécution ou inactifs, le nombre
 | 
						||
		d'interruptions et de changements de contexte par
 | 
						||
		seconde, et le pourcentage d'utilisation du CPU. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                    Voici la sortie de la commande <code>vmstat</code>
 | 
						||
		    pour un serveur inactif : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
                <example><pre>
 | 
						||
[sctemme@GayDeceiver sctemme]$ vmstat 5 3
 | 
						||
   procs                      memory     swap         io    system        cpu
 | 
						||
 r b w     swpd   free   buff cache si so       bi    bo in     cs us  sy id
 | 
						||
 0 0 0        0 186252   6688 37516    0    0   12     5 47    311  0   1 99
 | 
						||
 0 0 0        0 186244   6696 37516    0    0    0    16 41    314  0   0 100
 | 
						||
 0 0 0        0 186236   6704 37516    0    0    0     9 44    314  0   0 100
 | 
						||
                  </pre></example>
 | 
						||
                
 | 
						||
                <p>Et voici cette même sortie pour un serveur en charge
 | 
						||
		de cent connexions simultanées pour du contenu statique	: 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example><pre>
 | 
						||
[sctemme@GayDeceiver sctemme]$ vmstat 5 3
 | 
						||
   procs                      memory     swap    io      system       cpu
 | 
						||
 r b w     swpd   free   buff cache si so     bi bo   in     cs us sy  id
 | 
						||
 1 0 1        0 162580   6848 40056    0    0 11  5 150     324  1  1  98
 | 
						||
 6 0 1        0 163280   6856 40248    0    0  0 66 6384 1117   42 25  32
 | 
						||
11 0 0        0 162780   6864 40436    0    0  0 61 6309 1165   33 28  40
 | 
						||
                  </pre></example>
 | 
						||
                
 | 
						||
                <p>La première ligne indique des valeurs moyennes depuis
 | 
						||
		le dernier redémarrage. Les lignes suivantes donnent des
 | 
						||
		informations d'état à intervalles de 5 secondes. Le
 | 
						||
		second argument demande à vmstat de générer 3 lignes
 | 
						||
		d'état, puis de s'arrêter. 
 | 
						||
                </p>
 | 
						||
                 
 | 
						||
            </section>
 | 
						||
            <section id="se-toolkit">
 | 
						||
                <title>Boîte à outils SE
 | 
						||
                </title>
 | 
						||
                <p>La boîte à outils SE est une solution de supervision
 | 
						||
		pour Solaris. Son langage de programmation est basé sur
 | 
						||
		le préprocesseur C et est fourni avec de nombreux
 | 
						||
		exemples de scripts. Les informations fournies
 | 
						||
		peuvent être exploitées en mode console ou en mode
 | 
						||
		graphique. Cette boîte à outils peut aussi être programmée pour
 | 
						||
		appliquer des règles aux données système. Avec l'exemple
 | 
						||
		de script de la Figure 2, Zoom.se, des voyants verts,
 | 
						||
		oranges ou rouges s'allument lorsque certaines valeurs
 | 
						||
		du système dépassent un seuil spécifié. Un autre script
 | 
						||
		fourni, Virtual Adrian, permet d'affiner les
 | 
						||
		performances en tenant compte de ces valeurs. 
 | 
						||
                </p>
 | 
						||
                <p>Depuis sa création, de nombreux propriétaires se sont
 | 
						||
		succédés à la tête de la boîte à outils SE, et elle a de
 | 
						||
		ce fait largement évolué. Il semble qu'elle ait
 | 
						||
		maintenant trouvé sa place chez Sunfreeware.com d'où
 | 
						||
		elle peut être téléchargée gratuitement. Il n'y a qu'un
 | 
						||
		seul paquet pour Solaris 8, 9 et 10 sur SPARC et x86, et
 | 
						||
		il inclut le code source. Le concepteur de la boîte à
 | 
						||
		outils SE, Richard Pettit, a fondé une nouvelle sociéte,
 | 
						||
		Captive Metrics4, et a l'intention de mettre sur le
 | 
						||
		marché un outil de supervision multiplateforme en Java basé sur
 | 
						||
		les mêmes principes que la boîte à outils SE. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="dtrace">
 | 
						||
                <title>DTrace
 | 
						||
                </title>
 | 
						||
                <p>Etant donné que DTrace est disponible sous Solaris,
 | 
						||
		FreeBSD et OS X, il serait intéressant de l'étudier. Il
 | 
						||
		y a aussi le module mod_dtrace pour httpd. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="mod_status">
 | 
						||
                <title>mod_status
 | 
						||
                </title>
 | 
						||
                <p>Le module mod_status donne un aperçu des performances
 | 
						||
		du serveur à un instant donné. Il génère une page HTML
 | 
						||
		comportant, entre autres, le nombre de processus Apache
 | 
						||
		en cours d'exécution avec la quantité de données qu'ils
 | 
						||
		ont servies, ainsi que la charge CPU induite par httpd
 | 
						||
		et le reste du système. L'Apache Software Foundation
 | 
						||
		utilise elle-même <module>mod_status</module> pour son
 | 
						||
		propre <a href="http://apache.org/server-status">site
 | 
						||
		web</a>. Si vous ajoutez une directive
 | 
						||
		<code>ExtendedStatus On</code> à votre fichier
 | 
						||
		<code>httpd.conf</code>, la page de
 | 
						||
		<module>mod_status</module> vous fournira d'avantage
 | 
						||
		d'informations, au prix d'une consommation de ressources
 | 
						||
		légèrement supérieure par requête. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
        <section id="web-server-log-files">
 | 
						||
            <title>Les journaux du serveur web
 | 
						||
            </title>
 | 
						||
            <p>Le moyen le plus efficace pour vérifier la bonne santé et
 | 
						||
	    le niveau de performance de votre serveur consiste à
 | 
						||
	    surveiller et analyser les journaux écrits par httpd. La
 | 
						||
	    surveillance du journal des erreurs vous permet de
 | 
						||
	    déterminer les sources d'erreurs, de détecter des attaques
 | 
						||
	    ou des problèmes de performance. L'analyse du journal des
 | 
						||
	    accès vous indique le niveau de charge de votre serveur,
 | 
						||
	    quelles sont les ressources les plus populaires, ainsi que
 | 
						||
	    la provenance de vos utilisateurs. Une analyse historique des
 | 
						||
	    données de journalisation peut vous fournir des informations
 | 
						||
	    précieuses quant aux tendances d'utilisation de votre
 | 
						||
	    serveur au cours du temps, ce qui vous permet de prévoir les
 | 
						||
	    périodes où les besoins en performance risquent de dépasser
 | 
						||
	    les capacités du serveur. 
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
            <section id="ErrorLog">
 | 
						||
                <title>Journal des erreurs
 | 
						||
                </title>
 | 
						||
                <p>Le journal des erreurs peut indiquer que le nombre
 | 
						||
		maximum de processus actifs ou de fichiers ouverts
 | 
						||
		simultanément a été atteint. Le journal des erreurs
 | 
						||
		signele aussi le lancement de processus supplémentaires selon un
 | 
						||
		taux supérieur à la normale en réponse à
 | 
						||
		une augmentation soudaine de la charge. Lorsque le
 | 
						||
		serveur démarre, le descripteur de fichier stderr est
 | 
						||
		redirigé vers le journal des erreurs, si bien que toute
 | 
						||
		erreur rencontrée par httpd après avoir ouvert ses
 | 
						||
		fichiers journaux apparaîtra dans ce journal. Consulter
 | 
						||
		fréquemment le journal des erreurs est donc une bonne
 | 
						||
		habitude. 
 | 
						||
                </p>
 | 
						||
                <p>Lorsque Apache httpd n'a pas encore ouvert ses
 | 
						||
		fichiers journaux, tout message d'erreur sera envoyé
 | 
						||
		vers la sortie d'erreur standard stderr. Si vous
 | 
						||
		démarrez httpd manuellement, ces messages d'erreur
 | 
						||
		apparaîtront sur votre terminal, et vous pourrez les
 | 
						||
		utiliser directement pour résoudre les problèmes de
 | 
						||
		votre serveur. Si httpd est lancé via un script de
 | 
						||
		démarrage, la destination de ces messages d'erreur
 | 
						||
		dépend de leur conception.
 | 
						||
		<code>/var/log/messages</code> est alors le premier fichier à
 | 
						||
		consulter. Sous Windows, ces messages d'erreur précoces
 | 
						||
		sont écrits dans le journal des évènements des
 | 
						||
		applications, qui peut être visualisé via l'observateur
 | 
						||
		d'évènements dans les outils d'administration. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                    Le journal des erreurs est configuré via les
 | 
						||
		    directives de configuration <directive
 | 
						||
		    module="core">ErrorLog</directive> et <directive
 | 
						||
		    module="core">LogLevel</directive>. Le journal des
 | 
						||
		    erreurs de la configuration du serveur principal de
 | 
						||
		    httpd reçoit les messages d'erreur concernant
 | 
						||
		    l'ensemble du serveur : démarrage, arrêt, crashes,
 | 
						||
		    lancement de processus supplémentaires excessif,
 | 
						||
		    etc... La directive <directive
 | 
						||
		    module="core">ErrorLog</directive> peut aussi être
 | 
						||
		    utilisée dans les blocs de configuration des
 | 
						||
		    serveurs virtuels. Le journal des erreurs d'un
 | 
						||
		    serveur virtuel ne reçoit que les messages d'erreur
 | 
						||
		    spécifiques à ce serveur virtuel, comme les erreurs
 | 
						||
		    d'authentification et les erreurs du style 'File not
 | 
						||
		    Found'. 
 | 
						||
                </p>
 | 
						||
                <p>Dans le cas d'un serveur accessible depuis Internet,
 | 
						||
		attendez-vous à voir de nombreuses tentatives
 | 
						||
		d'exploitation et attaques de vers dans le journal des
 | 
						||
		erreurs. La plupart d'entre elles ciblent des serveurs
 | 
						||
		autres qu'Apache, mais dans l'état actuel des choses,
 | 
						||
		les scripts se contentent d'envoyer leurs attaques vers
 | 
						||
		tout port ouvert, sans tenir compte du serveur web
 | 
						||
		effectivement en cours d'exécution ou du type
 | 
						||
		des applications installées. Vous pouvez bloquer ces
 | 
						||
		tentatives d'attaque en utilisant un pare-feu ou le
 | 
						||
		module <a
 | 
						||
		href="http://www.modsecurity.org/">mod_security</a>,
 | 
						||
		mais ceci dépasse la portée de cette discussion. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                    La directive <directive
 | 
						||
		    module="core">LogLevel</directive> permet de définir
 | 
						||
		    le niveau de détail des messages enregistrés dans
 | 
						||
		    les journaux. Il existe huit niveaux de
 | 
						||
		    journalisation : 
 | 
						||
                </p>
 | 
						||
                <table>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p><strong>Niveau</strong></p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p><strong>Description</strong></p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>emerg</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Urgence - le système est inutilisable.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>alert</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Une action doit être entreprise
 | 
						||
			    immédiatement.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>crit</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Situations critiques.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>error</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Situations d'erreur.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>warn</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Situations provoquant un avertissement.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>notice</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Evènement normal, mais important.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>info</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Informations.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>debug</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Messages de débogage.</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                </table>
 | 
						||
                <p>Le niveau de journalisation par défaut est warn. Un
 | 
						||
		serveur en production ne doit pas s'exécuter en mode
 | 
						||
		debug, mais augmenter le niveau de détail dans le
 | 
						||
		journal des erreurs peut s'avérer utile pour résoudre
 | 
						||
		certains problèmes. A partir de la
 | 
						||
		version 2.3.8, la directive <directive
 | 
						||
		module="core">LogLevel</directive> peut être définie au
 | 
						||
		niveau de chaque module : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <highlight language="config">
 | 
						||
                    LogLevel debug mod_ssl:warn
 | 
						||
                </highlight>
 | 
						||
                
 | 
						||
                <p>
 | 
						||
                  Dans cet exemple, l'ensemble du serveur est en mode
 | 
						||
		  debug, sauf le module <module>mod_ssl</module>
 | 
						||
		  qui a tendance à être très bavard. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="AccessLog">
 | 
						||
                <title>Journal des accès
 | 
						||
                </title>
 | 
						||
                <p>Apache httpd garde la trace de toutes les requêtes
 | 
						||
		qu'il reçoit dans son journal des accès. En plus de
 | 
						||
		l'heure et de la nature d'une requête, httpd peut
 | 
						||
		enregistrer l'adresse IP du client, la date et l'heure
 | 
						||
		de la requête, le résultat et quantité d'autres
 | 
						||
		informations. Les différents formats de journaux sont
 | 
						||
		documentés dans le manuel. Le fichier concerne par
 | 
						||
		défaut le serveur principal, mais il peut être configuré
 | 
						||
		pour chaque serveur virtuel via les directives de
 | 
						||
		configuration  <directive
 | 
						||
		module="mod_log_config">TransferLog</directive> ou
 | 
						||
		<directive
 | 
						||
		module="mod_log_config">CustomLog</directive>. 
 | 
						||
                </p>
 | 
						||
                <p>De nombreux programmes libres ou commerciaux
 | 
						||
		permettent d'analyser les journaux d'accès. Analog et
 | 
						||
		Webalyser sont des programmes d'analyse libres parmi les
 | 
						||
		plus populaires. L'analyse des journaux doit s'effectuer
 | 
						||
		hors ligne afin de ne pas surcharger le serveur web avec
 | 
						||
		le traitement des fichiers journaux. La plupart des
 | 
						||
		programmes d'analyse des journaux sont compatibles avec le format
 | 
						||
		de journal "Common". Voici une description des
 | 
						||
		différents champs présents dans une entrée du journal :  
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
                <example><pre>
 | 
						||
195.54.228.42 - - [24/Mar/2007:23:05:11 -0400] "GET /sander/feed/ HTTP/1.1" 200 9747
 | 
						||
64.34.165.214 - - [24/Mar/2007:23:10:11 -0400] "GET /sander/feed/atom HTTP/1.1" 200 9068
 | 
						||
60.28.164.72 - - [24/Mar/2007:23:11:41 -0400] "GET / HTTP/1.0" 200 618
 | 
						||
85.140.155.56 - - [24/Mar/2007:23:14:12 -0400] "GET /sander/2006/09/27/44/ HTTP/1.1" 200 14172
 | 
						||
85.140.155.56 - - [24/Mar/2007:23:14:15 -0400] "GET /sander/2006/09/21/gore-tax-pollution/ HTTP/1.1" 200 15147
 | 
						||
74.6.72.187 - - [24/Mar/2007:23:18:11 -0400] "GET /sander/2006/09/27/44/ HTTP/1.0" 200 14172
 | 
						||
74.6.72.229 - - [24/Mar/2007:23:24:22 -0400] "GET /sander/2006/11/21/os-java/ HTTP/1.0" 200 13457
 | 
						||
                </pre></example>
 | 
						||
                
 | 
						||
                <table>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p><strong>Champ</strong></p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p><strong>Contenu</strong></p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p><strong>Explication</strong></p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Adresse IP client</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>195.54.228.42</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Adresse IP d'où provient la requête</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Identité RFC 1413</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>-</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                          <p>Identité de l'utilisateur distant renvoyée
 | 
						||
			  par son démon identd</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Nom utilisateur</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>-</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Nom de l'utilisateur distant issu de
 | 
						||
			    l'authentification Apache</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Horodatage</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>[24/Mar/2007:23:05:11 -0400]</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Date et heure de la requête</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Requête</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>"GET /sander/feed/ HTTP/1.1"</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>La requête proprement dite</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Code d'état</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>200</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Code d'état renvoyé avec la réponse</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                    <tr>
 | 
						||
                        <td>
 | 
						||
                            <p>Contenu en octets</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>9747</p>
 | 
						||
                        </td>
 | 
						||
                        <td>
 | 
						||
                            <p>Total des octets transférés sans les
 | 
						||
			    en-têtes</p>
 | 
						||
                        </td>
 | 
						||
                    </tr>
 | 
						||
                </table>
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="rotating-log-files">
 | 
						||
                <title>Rotation des fichiers journaux
 | 
						||
                </title>
 | 
						||
                <p>Il y a de nombreuses raisons pour mettre en oeuvre la
 | 
						||
		rotation des fichiers journaux. Même si pratiquement
 | 
						||
		plus aucun système d'exploitation n'impose une limite de
 | 
						||
		taille pour les fichiers de deux GigaOctets, avec le
 | 
						||
		temps, les fichiers journaux deviennent trop gros pour
 | 
						||
		pouvoir être traités. En outre, toute analyse de journal
 | 
						||
		ne doit pas être effectuée sur un fichier dans lequel le
 | 
						||
		serveur est en train d'écrire. Une rotation périodique
 | 
						||
		des fichiers journaux permet de faciliter leur analyse,
 | 
						||
		et de se faire une idée plus précise des habitudes
 | 
						||
		d'utilisation. 
 | 
						||
                </p>
 | 
						||
                <p>Sur les systèmes unix, vous pouvez simplement
 | 
						||
		effectuer cette rotation en changeant le nom du fichier
 | 
						||
		journal via la commande mv. Le serveur continuera à
 | 
						||
		écrire dans le fichier ouvert même s'il a changé de nom.
 | 
						||
		Lorsque vous enverrez un signal de redémarrage
 | 
						||
		"Graceful" au serveur, il ouvrira un nouveau fichier
 | 
						||
		journal avec le nom configuré par défaut. Par exemple,
 | 
						||
		vous pouvez écrire un script de ce style pour cron : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
                <example>
 | 
						||
                    APACHE=/usr/local/apache2<br />
 | 
						||
                    HTTPD=$APACHE/bin/httpd<br />
 | 
						||
                    mv $APACHE/logs/access_log
 | 
						||
                    $APACHE/logarchive/access_log-`date +%F`<br />
 | 
						||
                    $HTTPD -k graceful
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Cette approche fonctionne aussi sous Windows, mais
 | 
						||
		avec moins de souplesse. Alors que le processus httpd de
 | 
						||
		votre serveur sous Windows continuera à écrire dans le
 | 
						||
		fichier journal une fois ce dernier renommé, le service
 | 
						||
		Windows qui exécute Apache n'est pas en mesure
 | 
						||
		d'effectuer un redémarrage graceful. Sous Windows, le
 | 
						||
		redémarrage d'un service consiste simplement à l'arrêter
 | 
						||
		et à le démarrer à nouveau, alors qu'avec un redémarrage
 | 
						||
		graceful, les processus enfants terminent
 | 
						||
		le traitement des requêtes en cours avant de s'arrêter,
 | 
						||
		et le serveur httpd est alors immédiatement à
 | 
						||
		nouveau disponible pour traiter les nouvelles requêtes.
 | 
						||
		Sous Windows, le processus d'arrêt/redémarrage du
 | 
						||
		service interrompt les traitements de requêtes en cours,
 | 
						||
		et le serveur demeure indisponible jusqu'à ce qu'il ait
 | 
						||
		terminé son redémarrage. Vous devez donc tenir compte de
 | 
						||
		toutes ces contraintes lorsque vous planifiez un
 | 
						||
		redémarrage. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                  Une seconde approche consiste à utiliser la
 | 
						||
		  redirection des logs. Les directives <directive
 | 
						||
		  module="mod_log_config">CustomLog</directive>,
 | 
						||
		  <directive
 | 
						||
		  module="mod_log_config">TransferLog</directive> ou
 | 
						||
		  <directive module="core">ErrorLog</directive>
 | 
						||
		  permettent de rediriger les données de journalisation
 | 
						||
		  vers tout programme via le caractère pipe
 | 
						||
		  (<code>|</code>) comme dans cet exemple : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>CustomLog "|/usr/local/apache2/bin/rotatelogs
 | 
						||
                    /var/log/access_log 86400" common
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Le programme cible de la redirection recevra alors les
 | 
						||
		données de journalisation d'Apache sur son entrée
 | 
						||
		standard stdin, et pourra en faire ce qu'il voudra. Le
 | 
						||
		programme rotatelogs fourni avec Apache effectue une
 | 
						||
		rotation des journaux de manière transparente en
 | 
						||
		fonction du temps ou de la quantité de données écrites,
 | 
						||
		et archive l'ancien fichier journal en ajoutant un
 | 
						||
		suffixe d'horodatage à son nom. Cependant, si cette
 | 
						||
		méthode fonctionne de manière satisfaisante sur les
 | 
						||
		plateformes de style unix, il n'en est pas de même sous
 | 
						||
		Windows. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="logging-and-performance">
 | 
						||
                <title>Journalisation et performances
 | 
						||
                </title>
 | 
						||
                <p>L'écriture d'entrées dans les fichiers journaux est
 | 
						||
		consommatrice de ressources, mais l'importance de ces
 | 
						||
		données est telle qu'il est fortement déconseillé de
 | 
						||
		désactiver la journalisation. Pour optimiser les
 | 
						||
		performances, vous devez enregistrer vos journaux sur un
 | 
						||
		disque physique différent de celui où se situe votre
 | 
						||
		site web car les modes d'accès sont très différents. La
 | 
						||
		lecture de données sur un disque possède un caractère
 | 
						||
		essentiellement aléatoire, alors que l'écriture dans les
 | 
						||
		fichiers journaux s'effectue de manière séquentielle. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                  Ne définissez jamais la directive <directive
 | 
						||
		  module="core">LogLevel</directive> à debug pour un
 | 
						||
		  serveur en production. En effet, lorsque ce niveau de
 | 
						||
		  journalisation est défini, une grande quantité de
 | 
						||
		  données est écrite dans le journal des erreurs, y
 | 
						||
		  compris, dans le cas d'un accès SSL, toutes les
 | 
						||
		  opérations de lecture/écriture de la négociation de la
 | 
						||
		  connexion. Les implications en matière de performances
 | 
						||
		  sont donc importantes et vous devez plutôt utiliser le
 | 
						||
		  niveau de journalisation warn. 
 | 
						||
                </p>
 | 
						||
                <p>Si votre serveur possède plus d'un serveur virtuel,
 | 
						||
		il est conseillé d'attribuer un journal des accès séparé à
 | 
						||
		chacun d'entre eux, ce qui a pour effet de faciliter son
 | 
						||
		exploitation ultérieure. Par contre, si votre serveur
 | 
						||
		possède un grand nombre de serveurs virtuels, le nombre
 | 
						||
		de fichiers journaux à ouvrir va représenter une
 | 
						||
		consommation de ressources importante pour votre
 | 
						||
		système, et il sera peut-être alors plus judicieux
 | 
						||
		d'utiliser un seul fichier journal avec l'aménagement
 | 
						||
		suivant : utiliser l'élément de format <code>%v</code>
 | 
						||
		en tête de votre directive <directive
 | 
						||
		module="mod_log_config">LogFormat</directive> (et de
 | 
						||
		votre directive <directive
 | 
						||
		module="core">ErrorLog</directive> depuis la version
 | 
						||
		2.3.8) afin que httpd enregistre le nom du serveur
 | 
						||
		virtuel qui traite la requête ou l'erreur au début de
 | 
						||
		chaque entrée du journal. Un simple script Perl peut
 | 
						||
		alors éclater le journal en fichiers spécifiques à
 | 
						||
		chaque serveur virtuel après sa rotation ; Apache
 | 
						||
		fournit un tel script dans le répertoire
 | 
						||
		<code>support/split-logfile</code>.
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                    Vous pouvez aussi utiliser la directive <directive
 | 
						||
		    module="mod_log_config">BufferedLogs</directive>
 | 
						||
		    pour qu'Apache conserve en mémoire plusieurs entrées
 | 
						||
		    de journal avant de les écrire sur disque. Gardez
 | 
						||
		    cependant à l'esprit que si les performances peuvent
 | 
						||
		    s'en trouver améliorées, la chronologie des
 | 
						||
		    évènements enregistrés peut quant à elle s'en
 | 
						||
		    trouver affectée. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
        <section id="generating-a-test-load">
 | 
						||
            <title>Mise en oeuvre d'une charge de test
 | 
						||
            </title>
 | 
						||
            <p>Il est interessant de mettre en oeuvre une charge de test
 | 
						||
	    afin d'évaluer les performances du système en conditions
 | 
						||
	    réelles de fonctionnement. A cet effet, il existe des
 | 
						||
	    paquets commerciaux comme <a
 | 
						||
	    href="http://learnloadrunner.com/">LoadRunner</a>, mais
 | 
						||
	    aussi de nombreux outils libres permettant de générer une
 | 
						||
	    charge de test pour votre serveur web. 
 | 
						||
            </p>
 | 
						||
            <ul>
 | 
						||
                <li>Apache est fourni avec un programme de test nommé ab
 | 
						||
		(initiales de Apache Bench). Ce dernier peut générer une
 | 
						||
		charge de serveur web consistant à demander le même
 | 
						||
		fichier de manière répétitive à un rythme rapide. Vous
 | 
						||
		pouvez spécifier le nombre de connexions simultanées, et
 | 
						||
		choisir entre une durée de fonctionnement ou un nombre
 | 
						||
		de requêtes. 
 | 
						||
                </li>
 | 
						||
                <li>http load11 est un autre exemple de générateur de
 | 
						||
		charge libre. Ce programme fonctionne avec un ficher
 | 
						||
		d'URLs et peut être compilé avec le support SSL. 
 | 
						||
                </li>
 | 
						||
                <li>L'Apache Software Foundation propose un outil nommé
 | 
						||
		flood12. Flood est un programme assez sophistiqué que
 | 
						||
		l'on configure via un fichier XML. 
 | 
						||
                </li>
 | 
						||
                <li>Pour finir, JMeter13, un sous-projet de Jakarta, est
 | 
						||
		un outil de test en charge entièrement en Java. Alors
 | 
						||
		que les premières versions de cette application étaient
 | 
						||
		lentes et difficiles d'utilisation, la version 2.1.1
 | 
						||
		actuelle semble être plus souple d'utilisation et
 | 
						||
		efficace. 
 | 
						||
                </li>
 | 
						||
                <li>
 | 
						||
                    <p>Des projets externes à l'ASF et réputés
 | 
						||
		    relativement corrects : grinder, httperf, tsung, <a
 | 
						||
		    href="http://funkload.nuxeo.org/">FunkLoad</a>.
 | 
						||
                    </p>
 | 
						||
                </li>
 | 
						||
            </ul>
 | 
						||
            <p>Lorsque vous appliquez une charge de test à votre serveur
 | 
						||
	    web, gardez à l'esprit que si ce dernier est en production,
 | 
						||
	    la charge de test peut en affecter négativement les
 | 
						||
	    performances. En outre, le transfert de données
 | 
						||
	    supplémentaires induit peut être comptabilisé dans le
 | 
						||
	    quota mensuel qui vous a été éventuellement alloué.
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
        </section>
 | 
						||
    </section>
 | 
						||
    <section id="configuring-for-performance">
 | 
						||
        <title>Configuration dans une optique de performances
 | 
						||
        </title>
 | 
						||
        
 | 
						||
        
 | 
						||
        <section id="apache-configuration">
 | 
						||
            <title>Configuration de httpd
 | 
						||
            </title>
 | 
						||
            <p>httpd version 2.2 est par défaut un serveur web avec des
 | 
						||
	    processus enfants lancés au préalable. Au démarrage du
 | 
						||
	    serveur, le processus parent lance un certain nombre de
 | 
						||
	    processus enfants et ce sont eux qui seront chargés de traiter les
 | 
						||
	    requêtes. Mais avec httpd version 2.0 est apparu le concept
 | 
						||
	    de module multi-process (MPM). Les développeurs purent alors
 | 
						||
	    écrire des MPMs qui pouvaient fonctionner avec l'architecture
 | 
						||
	    à base de processus ou de threads de leur système
 | 
						||
	    d'exploitation spécifique. Apache 2 est fourni avec des MPMs
 | 
						||
	    spécifiques pour Windows, OS/2, Netware et BeOS. Pour les
 | 
						||
	    plateformes de style unix, les deux MPMS les plus connus
 | 
						||
	    sont Prefork et Worker. Le MPM Prefork offre le même modèle
 | 
						||
	    de processus enfants prélancés que celui d'Apache 1.3. Le
 | 
						||
	    MPM Worker quant à lui, lance un nombre de processus enfants
 | 
						||
	    moins important, mais attribue à chacun d'entre eux un
 | 
						||
	    certain nombre de threads pour traiter les requêtes. Avec la
 | 
						||
	    version 2.4, le MPM n'est plus défini à la compilation,
 | 
						||
	    mais peut être chargé à l'exécution via la directive
 | 
						||
	    <directive module="core">LoadModule</directive>. Le MPM par
 | 
						||
	    défaut pour la version 2.4 est le MPM event. 
 | 
						||
            </p>
 | 
						||
            <p>Le nombre maximum de process, à savoir le nombre de  processus
 | 
						||
	    enfants prélancés et/ou de threads, donne une approximation
 | 
						||
	    du nombre de requêtes que votre serveur peut traiter
 | 
						||
	    simultanément. Ce n'est cependant qu'une estimation car le
 | 
						||
	    noyau peut mettre en file d'attente des tentatives de
 | 
						||
	    connexion à votre serveur. Lorsque votre site approche de la
 | 
						||
	    saturation et si le nombre maximum de process est atteint, la
 | 
						||
	    machine n'impose pas de limite absolue au
 | 
						||
	    delà de laquelle les clients se verront refuser l'accès.
 | 
						||
	    Cependant, lorsque les requêtes commencent à être mises en
 | 
						||
	    file d'attente, les performances du système se dégradent
 | 
						||
	    rapidement. 
 | 
						||
            </p>
 | 
						||
	    <p>Enfin, si le serveur httpd en question n'exécute aucun
 | 
						||
	    code tiers via <code>mod_php</code>, <code>mod_perl</code>,
 | 
						||
	    etc..., nous recommandons l'utilisation de
 | 
						||
	    <module outdated="true">mpm_event</module>. Ce MPM est idéal pour les
 | 
						||
	    situations où httpd sert d'intermédiaire entre les clients
 | 
						||
	    et des serveurs d'arrière-plan qui accomplissent le travail
 | 
						||
	    proprement dit (par exemple en mode	mandataire ou cache).
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
            <section id="MaxClients">
 | 
						||
                <title>MaxClients
 | 
						||
                </title>
 | 
						||
                <p>La directive <code>MaxClients</code> permet de
 | 
						||
		spécifier le nombre maximum de process que votre serveur
 | 
						||
		pourra créer. Deux autres directives lui sont associées
 | 
						||
		: <code>MinSpareServers</code> et
 | 
						||
		<code>MaxSpareServers</code>, qui permettent d'encadrer
 | 
						||
		le nombre de process que httpd garde en réserve pour
 | 
						||
		traiter les requêtes. Le nombre total de process que
 | 
						||
		httpd peut créer peut
 | 
						||
		être défini via la directive <code>ServerLimit</code>. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="spinning-threads">
 | 
						||
                <title>Rotation des threads
 | 
						||
                </title>
 | 
						||
                <p>Les directives ci-dessus suffisent pour définir les
 | 
						||
		limites des nombres de process dans le cas du MPM Prefork.
 | 
						||
		Cependant, si vous utilisez un MPM à base de threads, la
 | 
						||
		situation est un peu plus compliquée. Les MPMs à base de
 | 
						||
		threads supportent la directive
 | 
						||
		<code>ThreadsPerChild</code>. httpd impose le fait que
 | 
						||
		<code>MaxClients</code> doit être divisible par
 | 
						||
		<code>ThreadsPerChild</code>. Si les valeurs que vous
 | 
						||
		attribuez à ces deux directives ne respectent pas cette
 | 
						||
		règle, httpd affichera un message d'erreur et corrigera
 | 
						||
		la valeur de la directive <code>ThreadsPerChild</code>
 | 
						||
		en la diminuant jusqu'à ce que la valeur de la directive
 | 
						||
		<code>MaxClients</code> soit divisible par elle.
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="sizing-maxClients">
 | 
						||
                <title>Choix de la valeur de MaxClients
 | 
						||
                </title>
 | 
						||
                <p>Idéalement, le nombre maximum de processus devrait
 | 
						||
		être choisi de façon à ce que toute la mémoire système
 | 
						||
		soit utilisée, sans la dépasser. En effet, si votre
 | 
						||
		système est surchargé au point de devoir faire appel de
 | 
						||
		manière intensive au swap (utilisation de la mémoire
 | 
						||
		disque), les performances vont se dégrader rapidement.
 | 
						||
		La formule permettant de déterminer la valeur de
 | 
						||
		<directive module="mpm_common"
 | 
						||
		name="MaxRequestWorkers">MaxClients</directive>
 | 
						||
		est assez simple : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>
 | 
						||
                    MaxClients = (RAM totale − RAM système − RAM pour
 | 
						||
		    les programmes externes) divisé par la RAM nécessaire pour
 | 
						||
		    chaque processus enfant.
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>L'observation est la meilleure manière de déterminer
 | 
						||
		les différentes quantités de mémoire allouées au
 | 
						||
		système, aux programmes externes et aux processus httpd
 | 
						||
		: à cet effet, vous pouvez utiliser les commandes top et
 | 
						||
		free décrites plus haut pour étudier l'empreinte mémoire
 | 
						||
		du système lorsque le serveur web n'est pas en cours
 | 
						||
		d'exécution. Vous pouvez aussi étudier l'empreinte d'un
 | 
						||
		processus type du serveur web via la commande top ; en
 | 
						||
		effet, la plupart des implémentations de cette commande
 | 
						||
		présentent une colonne Mémoire résidente (RSS - Resident
 | 
						||
		Size) et Mémoire partagée (Shared Memory). 
 | 
						||
                </p>
 | 
						||
                <p>La différence entre ces deux colonnes est la
 | 
						||
		quantité de mémoire par processus. Le segment de mémoire
 | 
						||
		partagée n'existe effectivement qu'une seule fois, et
 | 
						||
		est utilisé par le code et les bibliothèques chargées et
 | 
						||
		la concurrence inter-processus (ou tableau de résultat -
 | 
						||
		scoreboard) géré par Apache. La quantité de mémoire
 | 
						||
		utilisée par chaque processus dépend fortement du nombre
 | 
						||
		et du type de modules utilisés. La meilleure façon d'en
 | 
						||
		déterminer les besoins consiste à générer une charge
 | 
						||
		type pour votre site web et à observer l'importance que
 | 
						||
		prennent les processus httpd. 
 | 
						||
                </p>
 | 
						||
                <p>La RAM pour les programmes externes comprend
 | 
						||
		principalement la mémoire utilisée pour les programmes
 | 
						||
		CGI et les scripts qui s'exécutent indépendamment des
 | 
						||
		processus httpd. Par contre, si vous utilisez une
 | 
						||
		machine virtuelle Java qui exécute Tomcat sur le même
 | 
						||
		serveur, cette dernière va aussi nécessiter une quantité
 | 
						||
		de mémoire significative. En conséquence, la formule
 | 
						||
		ci-dessus qui sert à calculer la valeur maximale de
 | 
						||
		<code>MaxClients</code> permet d'effectuer une première approche,
 | 
						||
		mais ne constitue en aucun cas une science exacte. En
 | 
						||
		cas de doute, soyez pragmatique et utilisez une valeur assez
 | 
						||
		basse pour <code>MaxClients</code>. Le noyau Linux
 | 
						||
		réserve une certaine quantité de mémoire pour la mise en
 | 
						||
		cache des accès disque. Sous Solaris par contre, il faut disposer
 | 
						||
		de suffisamment de mémoire RAM pour créer un processus,
 | 
						||
		et si ce n'est pas le cas, httpd va démarrer avec un
 | 
						||
		message d'erreur du style "No space left on device" dans
 | 
						||
		le journal des erreurs, et sera incapable de créer
 | 
						||
		d'autres processus httpd enfants ; une valeur trop
 | 
						||
		élevée pour <code>MaxClients</code> constituera alors
 | 
						||
		réellement un désavantage. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="selecting-your-mpm">
 | 
						||
                <title>Choisir votre MPM
 | 
						||
                </title>
 | 
						||
                <p>La commutation entre threads est plus
 | 
						||
		aisée pour le système, et ceux-ci consomment moins de
 | 
						||
		ressources que les processus ; c'est la raison
 | 
						||
		principale pour	laquelle il est recommandé de choisir un
 | 
						||
		MPM threadé. Et
 | 
						||
		ceci est encore plus flagrant pour certains systèmes
 | 
						||
		d'exploitation que pour d'autres. Par exemple, sous
 | 
						||
		Solaris ou AIX, la manipulation des processus est assez
 | 
						||
		lourde en termes de ressources système ; l'utilisation
 | 
						||
		d'un MPM threadé est donc tout à fait indiquée pour ces
 | 
						||
		systèmes. Sous Linux en revanche, l'implémentation des
 | 
						||
		threads utilise en fait un processus par thread. Les
 | 
						||
		processus Linux sont assez légers, mais cela signifie qu'un
 | 
						||
		MPM threadé présentera ici un gain en performance
 | 
						||
		moindre que sous d'autres systèmes. 
 | 
						||
                </p>
 | 
						||
                <p>Dans certaines situations cependant, l'utilisation
 | 
						||
		d'un MPM threadé peut induire des problèmes de
 | 
						||
		stabilité. Par exemple, si un processus enfant du MPM
 | 
						||
		prefork se crashe, au plus une connexion client sera
 | 
						||
		affectée ; par contre, si un processus enfant threadé se
 | 
						||
		crashe, ce sont tous les threads de ce processus qui
 | 
						||
		vont se crasher à leur tour, ce qui signifie que tous
 | 
						||
		les clients qui étaient servis par ce processus verront
 | 
						||
		leur connexion interrompue. De plus, certains problèmes
 | 
						||
		de sécurité des threads ("thread-safety")
 | 
						||
		peuvent apparaître, particulièrement avec les
 | 
						||
		bibliothèques tierces. Avec les applications threadées,
 | 
						||
		les différents threads peuvent avoir accès aux mêmes
 | 
						||
		variables sans distinction, sans savoir si une variable
 | 
						||
		n'a pas été modifiée par un autre thread.
 | 
						||
                </p>
 | 
						||
                <p>Ce problème a fait l'objet d'un point sensible au
 | 
						||
		sein de la communauté PHP car Le processeur PHP repose
 | 
						||
		fortement sur des bibliothèques tierces, et il n'est pas
 | 
						||
		garanti que la totalité d'entre elles soient
 | 
						||
		"thread-safe". Bonne nouvelle cependant : si vous
 | 
						||
		exécutez Apache sous Linux, vous pouvez utiliser PHP
 | 
						||
		avec le MPM prefork sans craindre une diminution de
 | 
						||
		performance trop importante par rapport à une option
 | 
						||
		threadée. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="spinning-locks">
 | 
						||
                <title>Verrous tournants</title>
 | 
						||
                <p>Apache httpd maintient un verrou inter-processus du
 | 
						||
		point de vue de son écoute du réseau. Dans les faits,
 | 
						||
		cela signifie qu'un seul processus httpd enfant à la
 | 
						||
		fois peut recevoir une requête. Ainsi, soient les autres
 | 
						||
		processus en profitent alors pour traiter les requêtes
 | 
						||
		qu'ils ont déjà reçues, soient ils attendent de pouvoir
 | 
						||
		à leur tour récupérer le verrou et ainsi écouter le
 | 
						||
		réseau pour recevoir une nouvelle requête. Ceci peut se
 | 
						||
		voir comme une porte tournante par laquelle un seul
 | 
						||
		processus peut passer à la fois. Sur un serveur web
 | 
						||
		fortement chargé où les requêtes arrivent constamment,
 | 
						||
		la porte tourne rapidement et les requêtes sont
 | 
						||
		acceptées à un rythme soutenu. Sur un serveur faiblement
 | 
						||
		chargé en revanche, le processus qui "détient"
 | 
						||
		le verrou est suceptible de garder sa porte ouverte un
 | 
						||
		certain temps durant lequel tous les autres processus
 | 
						||
		seront inactifs, attendant de pouvoir s'approprier le
 | 
						||
		verrou. Dans une telle situation, le processus parent
 | 
						||
		pourra décider d'arrêter quelques processus enfants en
 | 
						||
		fonction de la valeur de la directive
 | 
						||
		<code>MaxSpareServers</code>.</p>
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="the-thundering-herd">
 | 
						||
                <title>L'assaut de la foule
 | 
						||
                </title>
 | 
						||
                <p>La fonction de l'"accept mutex" (c'est le nom donné au
 | 
						||
		verrou inter-processus) consiste à gérer la réception
 | 
						||
		des requêtes de manière ordonnée. Si ce verrou est
 | 
						||
		absent, le syndrome de l'"assaut de la foule" peut
 | 
						||
		apparaître. 
 | 
						||
                </p>
 | 
						||
                <p>Imaginez une équipe de football américain en attente
 | 
						||
		devant la ligne de remise en jeu. Si les joueurs se
 | 
						||
		comportaient comme des processus Apache, ils se
 | 
						||
		précipiteraient tous à la fois pour récupérer la balle au
 | 
						||
		signal de la reprise. Un seul d'entre eux y
 | 
						||
		parviendrait, et tous les autres n'auraient plus qu'à se
 | 
						||
		regrouper à nouveau sur la ligne jusqu'à la reprise
 | 
						||
		suivante. Dans cette métaphore, c'est le quaterback qui
 | 
						||
		va jouer le rôle d'"accept mutex" en donnant la balle
 | 
						||
		au joueur approprié. 
 | 
						||
                </p>
 | 
						||
                <p>La transmission d'une telle quantité d'informations
 | 
						||
		représente naturellement beaucoup de travail et, comme
 | 
						||
		une personne intelligente, un serveur intelligent
 | 
						||
		tentera d'éviter cette surcharge dans la mesure du
 | 
						||
		possible, d'où l'idée de la porte tournante. Dans les
 | 
						||
		dernières années, de nombreux systèmes d'exploitation,
 | 
						||
		comme Linux et Solaris, ont développé du code pour
 | 
						||
		éviter le syndrome de l'"assaut de la foule". Apache
 | 
						||
		reconnaît ce code, et si vous n'effectuez qu'une seule
 | 
						||
		écoute du réseau, autrement dit si vous n'utilisez que
 | 
						||
		le serveur principal ou un seul serveur virtuel, Apache
 | 
						||
		n'utilisera pas d'"accept mutex" ; par contre, si vous
 | 
						||
		effectuez plusieurs écoutes du réseau (par exemple si
 | 
						||
		un serveur virtuel sert les requêtes SSL), Apache
 | 
						||
		utilisera un "accept mutex" afin d'éviter les conflits
 | 
						||
		internes. 
 | 
						||
                </p>
 | 
						||
                <p>Vous pouvez manipuler l'"accept mutex" via la
 | 
						||
		directive <code>AcceptMutex</code>. Cette dernière
 | 
						||
		permet en particulier de fermer l'"accept mutex", mais
 | 
						||
		aussi de sélectionner le mécanisme de verrouillage. Les
 | 
						||
		mécanismes de verrouillage courants comprennent fcntl,
 | 
						||
		les sémaphores System V et le verrouillage par threads.
 | 
						||
		Tous ne sont pas supportés par toutes les plateformes,
 | 
						||
		et leur disponibilité dépend aussi des options de
 | 
						||
		compilation. Les différents mécanismes de verrouillage
 | 
						||
		peuvent avoir des exigences particulières en matière de
 | 
						||
		ressources système ; il est donc recommandé de les
 | 
						||
		utiliser avec précautions. 
 | 
						||
                </p>
 | 
						||
                <p>Il n'existe aucune raison particulière pour
 | 
						||
		désactiver l'"accept mutex". Apache détermine
 | 
						||
		automatiquement s'il doit utiliser ou non mutex sur
 | 
						||
		votre plateforme en fonction du nombre d'écoutes réseau
 | 
						||
		de votre serveur, comme décrit précédemment. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
        <section id="tuning-the-operating-system">
 | 
						||
            <title>Optimisation du système d'exploitation
 | 
						||
            </title>
 | 
						||
            <p>Souvent, les utilisateurs recherchent le paramètre magique qui va
 | 
						||
	    multiplier par quatre les performances de leur système. En
 | 
						||
	    fait, les systèmes de type Unix actuels sont déjà optimisés
 | 
						||
	    à l'origine, et il n'y a plus grand chose à faire pour
 | 
						||
	    améliorer leurs performances. L'administrateur peut
 | 
						||
	    cependant encore effectuer quelques modifications qui
 | 
						||
	    permettront de peaufiner la configuration. 
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
            <section id="ram-and-swap-space">
 | 
						||
                <title>RAM et swap
 | 
						||
                </title>
 | 
						||
                <p>Le leitmotiv en matière de mémoire est souvent "plus
 | 
						||
		on en a, mieux c'est". En effet, comme nous avons dit
 | 
						||
		plus haut, la mémoire inutilisée peut être
 | 
						||
		avantageusement utilisée comme cache du système de
 | 
						||
		fichiers. Plus vous chargez de modules, plus les processus
 | 
						||
		Apache grossissent, et ceci d'autant plus si vous
 | 
						||
		utilisez des modules qui génèrent des contenus
 | 
						||
		dynamiques comme PHP et mod_perl. Un gros fichier de
 | 
						||
		configuration - avec de nombreux serveurs virtuels - a
 | 
						||
		aussi tendance à augmenter l'empreinte mémoire des
 | 
						||
		processus. Une quantité de mémoire importante vous
 | 
						||
		permettra d'exécuter Apache avec plus de processus
 | 
						||
		enfants, et donc de traiter d'avantage de requêtes
 | 
						||
		simultanément. 
 | 
						||
                </p>
 | 
						||
                <p>Même si les différentes plateformes traitent leur
 | 
						||
		mémoire virtuelle de différentes manières, il est
 | 
						||
		déconseillé de configurer un espace disque de swap
 | 
						||
		inférieur à la mémoire RAM. En effet, le système de mémoire
 | 
						||
		virtuelle a été conçu de manière à prendre le relai
 | 
						||
		lorsque la mémoire RAM fait défaut, et lorsque l'espace
 | 
						||
		disque, et donc l'espace de swap vient à manquer, votre
 | 
						||
		serveur risque de s'arrêter. Vous devrez alors
 | 
						||
		redémarrer physiquement votre serveur, et votre
 | 
						||
		hébergeur pourra vous facturer le service. 
 | 
						||
                </p>
 | 
						||
                <p>Evidemment, ce genre problème survient au moment le
 | 
						||
		plus défavorable : lorsque le monde vient découvrir votre
 | 
						||
		site web et se présente avec insistance à votre porte.
 | 
						||
		Si votre espace de swap est suffisant, même si la
 | 
						||
		machine sera de plus en plus surchargée et deviendra
 | 
						||
		très très lente car le système devra swapper les pages
 | 
						||
		entre la mémoire et le disque, lorsque la charge diminuera à
 | 
						||
		nouveau, le système reviendra dans son mode de
 | 
						||
		fonctionnement normal. Rappelez-vous que vous disposez
 | 
						||
		de la directive <code>MaxClients</code> pour garder le contrôle.
 | 
						||
                </p>
 | 
						||
                <p>La plupart des systèmes de type Unix utilisent des
 | 
						||
		partitions dédiées au swap. Au démarrage du système,
 | 
						||
		celui-ci enregistre toutes les partitions de swap du ou
 | 
						||
		des disques en fonction du type de la partition ou du
 | 
						||
		contenu du fichier <code>/etc/fstab</code> et les
 | 
						||
		active de manière automatique. Lorsque vous ajoutez un
 | 
						||
		disque, ou lorsque vous installez le système
 | 
						||
		d'exploitation, assurez-vous d'allouer suffisamment
 | 
						||
		d'espace de swap afin de rester en adéquation avec une
 | 
						||
		éventuelle augmentation de la mémoire RAM. La
 | 
						||
		réallocation d'espace disque sur un système en
 | 
						||
		production est en effet pénible et fastidieuse. 
 | 
						||
                </p>
 | 
						||
                <p>Prévoyez un espace de swap de deux fois la taille de
 | 
						||
		votre mémoire RAM, et même jusqu'à quatre fois lorsque
 | 
						||
		les surcharges peuvent s'avérer fréquentes. Assurez-vous
 | 
						||
		de réajuster ces valeurs lorsque vous augmentez la
 | 
						||
		quantité de mémoire RAM de votre système. En secours,
 | 
						||
		vous pouvez aussi utilisez un fichier comme espace de
 | 
						||
		swap. Pour ce faire, vous trouverez les instructions
 | 
						||
		dans les pages de manuel de <code>mkswap</code> et
 | 
						||
		<code>swapon</code>, ou dans celles des programmes de
 | 
						||
		<code>swap</code>. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
               
 | 
						||
            </section>
 | 
						||
            <section id="ulimit-files-and-processes">
 | 
						||
                <title>ulimit: fichiers et processus
 | 
						||
                </title>
 | 
						||
                <p>Supposons que vous disposiez d'une machine possédant
 | 
						||
		une énorme quantité de mémoire RAM et un processeur aux
 | 
						||
		performances astronomiques ; vous pourrez alors exécuter
 | 
						||
		des centaines de processus Apache selon vos besoins,
 | 
						||
		mais tout en restant en deçà des limites imposées par le
 | 
						||
		noyau de votre système. 
 | 
						||
                </p>
 | 
						||
                <p>Considérez maintenant une situation où plusieurs
 | 
						||
		centaines de serveurs web sont en cours d'exécution ; si
 | 
						||
		certains d'entre eux doivent à leur tour lancer des
 | 
						||
		processus CGI, le nombre maximum de processus autorisé
 | 
						||
		par le noyau sera vite atteint.
 | 
						||
                </p>
 | 
						||
                <p>Dans ce cas, vous pouvez modifier cette limite avec
 | 
						||
		la commande : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>
 | 
						||
                    ulimit [-H|-S] -u [nouvelle valeur]
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Cette modification doit être effectuée avant le
 | 
						||
		démarrage du serveur, car la nouvelle valeur ne sera
 | 
						||
		prise en compte que dans le shell courant et pour les
 | 
						||
		programmes lancés depuis ce dernier. Dans les derniers
 | 
						||
		noyaux Linux, la valeur par défaut a été fixée à 2048.
 | 
						||
		Sous FreeBSD, ce nombre semble être limité à la valeur
 | 
						||
		inhabituelle de 513. Dans le shell par défaut de ce
 | 
						||
		système, <code>csh</code>, la commande équivalente est
 | 
						||
		<code>limit</code> et possède une syntaxe analogue à
 | 
						||
		celle de la commande de style Bourne <code>ulimit</code> :
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>
 | 
						||
                    limit [-h] maxproc [newvalue]
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>En outre, le noyau peut limiter le nombre de fichiers
 | 
						||
		ouverts par processus. Ce n'est généralement pas un
 | 
						||
		problème pour les serveurs dont les processus sont lancés
 | 
						||
		à l'avance, et où chacun de ceux-ci ne traite qu'une
 | 
						||
		requête à la fois. Les processus des serveurs threadés,
 | 
						||
		quant à eux, traitent plusieurs requêtes simultanément,
 | 
						||
		et sont d'avantage susceptibles de dépasser la limite du
 | 
						||
		nombre de descripteurs de fichiers. Vous pouvez alors
 | 
						||
		augmenter cette valeur limite du nombre de fichiers
 | 
						||
		ouverts avec la commande : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>ulimit -n [newvalue]
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Là encore, cette modification doit être effectuée
 | 
						||
		avant le démarrage du serveur Apache. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="setting-user-limits-on-system-startup">
 | 
						||
                <title>Définition des limites en fonction de l'utilisateur ou du
 | 
						||
		groupe au démarrage du système
 | 
						||
                </title>
 | 
						||
                <p>Sous Linux, vous pouvez définir les paramètres de
 | 
						||
		ulimit au démarrage en éditant le fichier
 | 
						||
		<code>/etc/security/limits.conf</code>. Ce fichier vous
 | 
						||
		permet de définir des limites "soft" et "hard"
 | 
						||
		en fonction de l'utilisateur ou du groupe ;
 | 
						||
		vous y trouverez aussi des commentaires explicatifs des
 | 
						||
		différentes options. Pour que ce fichier soit pris en
 | 
						||
		compte, le fichier <code>/etc/pam.d/login</code> doit
 | 
						||
		contenir la ligne : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>session required /lib/security/pam_limits.so
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Chaque item peut posséder une valeur "soft" et
 | 
						||
		"hard" : la première est la valeur
 | 
						||
		par défaut, et la seconde la valeur maximale de cet
 | 
						||
		item. 
 | 
						||
                </p>
 | 
						||
                <p>Dans le fichier <code>/etc/login.conf</code> de
 | 
						||
		FreeBSD, ces valeurs peuvent être limitées ou étendues à
 | 
						||
		tout le système de manière analogue au fichier
 | 
						||
		<code>limits.conf</code>. Les limites "soft" sont
 | 
						||
		spécifiées via le paramètre <code>-cur</code>, et les
 | 
						||
		limites "hard" via le paramètre <code>-max</code>.
 | 
						||
                </p>
 | 
						||
                <p>Solaris possède un mécanisme similaire pour manipuler
 | 
						||
		les valeurs limites au démarrage du système : dans le
 | 
						||
		fichier <code>/etc/system</code>, vous pouvez définir au
 | 
						||
		démarrage des paramètres du noyau valables pour
 | 
						||
		l'ensemble du système. Ce sont les mêmes paramètres que
 | 
						||
		ceux définis à l'exécution par le débogueur de noyau
 | 
						||
		<code>mdb</code>. Les commandes équivalentes à ulimit -u
 | 
						||
		pour définir les limites hard et soft seront du style : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>
 | 
						||
                    set rlim_fd_max=65536<br />
 | 
						||
                    set rlim_fd_cur=2048
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Solaris calcule le nombre maximal de processus
 | 
						||
		autorisé par utilisateur (<code>maxuprc</code>) en
 | 
						||
		fonction de la mémoire système disponible
 | 
						||
		(<code>maxusers</code>). Vous pouvez obtenir ces valeurs
 | 
						||
		avec la commande : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>sysdef -i | grep maximum
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Il est cependant déconseillé de les modifier. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
            <section id="turn-off-unused-services-and-modules">
 | 
						||
                <title>Désactiver les services et modules non utilisés
 | 
						||
                </title>
 | 
						||
                <p>Dans la plupart des distributions Unix et Linux, de
 | 
						||
		nombreux services sont activés par défaut, et vous n'
 | 
						||
		avez probablement besoin que d'une minorité d'entre eux.
 | 
						||
		Par exemple, votre serveur web n'a pas besoin de
 | 
						||
		sendmail, de fournir le service NFS, etc... Désactivez
 | 
						||
		les tout simplement. 
 | 
						||
                </p>
 | 
						||
                <p>Pour ce faire, sous RedHat Linux, vous
 | 
						||
		disposez de l'utilitaire chkconfig en ligne de commande.
 | 
						||
		Sous Solaris, les commandes <code>svcs</code> et
 | 
						||
		<code>svcadm</code> vous permettent respectivement
 | 
						||
		de lister les services activés et de désactiver ceux
 | 
						||
		dont vous n'avez pas besoin. 
 | 
						||
                </p>
 | 
						||
                <p>Vous devez aussi prêter attention aux modules Apache
 | 
						||
		chargés par défaut. La plupart des distributions binaires
 | 
						||
		d'Apache httpd et des versions préinstallées fournies
 | 
						||
		avec les distributions de Linux chargent les modules
 | 
						||
		Apache via la directive
 | 
						||
		<directive>LoadModule</directive>. 
 | 
						||
                </p>
 | 
						||
                <p>Les modules inutilisés peuvent être désactivés : si
 | 
						||
		vous n'avez pas besoin de leurs fonctionnalités et des
 | 
						||
		directives de configuration qu'ils implémentent,
 | 
						||
		désactivez-les en commentant les lignes
 | 
						||
		<directive>LoadModule</directive> correspondantes. Vous
 | 
						||
		devez cependant lire la documentation relative à ces
 | 
						||
		modules avant de les désactiver, et garder à l'esprit que
 | 
						||
		la désactivation d'un module très peu gourmand en
 | 
						||
		ressources n'est pas absolument nécessaire. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
    </section>
 | 
						||
    <section id="caching-content">
 | 
						||
        <title>Mise en cache des contenus
 | 
						||
        </title>
 | 
						||
        <p>Les requêtes impliquant des contenus dynamiques nécessitent
 | 
						||
	en général d'avantage de ressources que les
 | 
						||
	requêtes pour des contenus statiques. Les contenus statiques
 | 
						||
	consistent en simples pages issues de documents ou images
 | 
						||
	sur disque, et sont servis très rapidement. En outre, de
 | 
						||
	nombreux systèmes d'exploitation mettent automatiquement en
 | 
						||
	cache en mémoire les contenus des fichiers fréquemment accédés. 
 | 
						||
        </p>
 | 
						||
        <p>Comme indiqué précédemment, le traitement des requêtes dynamiques peut
 | 
						||
	nécessiter beaucoup plus de ressources. L'exécution de scripts
 | 
						||
	CGI, le transfert de requêtes à un serveur d'applications
 | 
						||
	externe, ou les accès à une base de données peuvent impliquer
 | 
						||
	des temps d'attente et charges de travail significatifs pour un
 | 
						||
	serveur web fortement sollicité. Dans de nombreuses
 | 
						||
	circonstances, vous pourrez alors améliorer les performances en
 | 
						||
	transformant les requêtes dynamiques courantes en requêtes
 | 
						||
	statiques. Pour ce faire, deux approches seront discutées dans
 | 
						||
	la suite de cette section. 
 | 
						||
        </p>
 | 
						||
        
 | 
						||
        
 | 
						||
        <section id="making-popular-pages-static">
 | 
						||
            <title>Transformation des pages courantes en contenus
 | 
						||
	    statiques
 | 
						||
            </title>
 | 
						||
            <p>En générant à l'avance les réponses pour les requêtes les
 | 
						||
	    plus courantes de votre application, vous pouvez améliorer
 | 
						||
	    de manière significative les performances de votre serveur
 | 
						||
	    sans abandonner la flexibilité des contenus générés
 | 
						||
	    dynamiquement. Par exemple, si votre application est un
 | 
						||
	    service de livraison de fleurs, vous aurez tout intérêt à
 | 
						||
	    générer à l'avance les pages de votre catalogue concernant
 | 
						||
	    les roses rouges dans les semaines précédant le jour de la
 | 
						||
	    Saint Valentin. Lorsqu'un utilisateur cherchera des roses
 | 
						||
	    rouges, il téléchargera alors les pages générées à
 | 
						||
	    l'avance. Par contre, les recherches de roses jaunes seront
 | 
						||
	    quant à elles traitées directement via une requête vers la
 | 
						||
	    base de données. Pour effectuer ces aiguillages de requêtes,
 | 
						||
	    vous disposez d'un outil particulièrement approprié fourni
 | 
						||
	    avec Apache : le module mod_rewrite. 
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
            <section id="example-a-statically-rendered-blog">
 | 
						||
                <title>Exemple : un blog servi statiquement
 | 
						||
                </title>
 | 
						||
                    <!--we should provide a more useful example here.
 | 
						||
                        One showing how to make Wordpress or Drupal suck less. -->
 | 
						||
                    
 | 
						||
                <p>Blosxom est un programme CGI de journalisation web
 | 
						||
		léger. Il est écrit en Perl et utilise des fichiers
 | 
						||
		texte pour ses entrées. Outre sa qualité de programme
 | 
						||
		CGI, Blosxom peut être exécuté en ligne de commande pour
 | 
						||
		générer à l'avance des pages de blog. Lorsque votre blog
 | 
						||
		commence à être lu par un grand nombre de personnes, la
 | 
						||
		génération à l'avance de pages en HTML satique peut
 | 
						||
		améliorer de manière significative les performances de
 | 
						||
		votre serveur. 
 | 
						||
                </p>
 | 
						||
                <p>Pour générer des pages statiques avec blosxom, éditez
 | 
						||
		le script CGI selon la documentation. Définissez la
 | 
						||
		variable $static dir à la valeur de
 | 
						||
		<directive>DocumentRoot</directive> de votre serveur
 | 
						||
		web, et exécutez le script en ligne de commande comme
 | 
						||
		suit : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                <example>$ perl blosxom.cgi -password='whateveryourpassword'
 | 
						||
                </example>
 | 
						||
                
 | 
						||
                <p>Vous pouvez exécuter ce script périodiquement via
 | 
						||
		cron, à chaque fois que vous ajoutez un nouveau contenu. Pour
 | 
						||
		faire en sorte qu'Apache substitue les pages
 | 
						||
		statiques au contenu dynamique, nous
 | 
						||
		utiliserons mod_rewrite. Ce module est fourni avec le
 | 
						||
		code source d'Apache, mais n'est pas compilé par défaut.
 | 
						||
		Pour le compiler avec la distribution d'Apache, vous
 | 
						||
		pouvez utiliser l'option de la commande configure
 | 
						||
		<code>--enable-rewrite[=shared]</code>. De nombreuses
 | 
						||
		distributions binaires d'Apache sont fournies avec
 | 
						||
		<module>mod_rewrite</module> inclus. Dans l'exemple
 | 
						||
		suivant, un serveur virtuel Apache utilise les pages de
 | 
						||
		blog générées à l'avance : 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
<highlight language="config">
 | 
						||
Listen *:8001
 | 
						||
  <VirtualHost *:8001>
 | 
						||
      ServerName blog.sandla.org:8001
 | 
						||
      ServerAdmin sander@temme.net
 | 
						||
      DocumentRoot "/home/sctemme/inst/blog/httpd/htdocs"
 | 
						||
      <Directory "/home/sctemme/inst/blog/httpd/htdocs">
 | 
						||
          Options +Indexes
 | 
						||
          Require all granted
 | 
						||
          RewriteEngine on
 | 
						||
          RewriteCond "%{REQUEST_FILENAME}" "!-f"
 | 
						||
          RewriteCond "%{REQUEST_FILENAME}" "!-d"
 | 
						||
          RewriteRule "^(.*)$" "/cgi-bin/blosxom.cgi/$1" [L,QSA]
 | 
						||
      </Directory>
 | 
						||
      RewriteLog "/home/sctemme/inst/blog/httpd/logs/rewrite_log"
 | 
						||
      RewriteLogLevel 9
 | 
						||
      ErrorLog "/home/sctemme/inst/blog/httpd/logs/error_log"
 | 
						||
      LogLevel debug
 | 
						||
      CustomLog "/home/sctemme/inst/blog/httpd/logs/access_log common"
 | 
						||
      ScriptAlias "/cgi-bin/" "/home/sctemme/inst/blog/bin/"
 | 
						||
      <Directory "/home/sctemme/inst/blog/bin">
 | 
						||
          Options +ExecCGI
 | 
						||
          Require all granted
 | 
						||
      </Directory>
 | 
						||
  </VirtualHost>
 | 
						||
</highlight>
 | 
						||
                
 | 
						||
                <p>
 | 
						||
                    Si les directives <directive>RewriteCond</directive>
 | 
						||
		    indiquent que la ressource demandée n'existe ni en tant que
 | 
						||
		    fichier, ni en tant que répertoire, son
 | 
						||
		    chemin sera redirigé par la directive		    
 | 
						||
		    <directive>RewriteRule</directive> vers le programme
 | 
						||
		    CGI Blosxom qui va générer la réponse. Blosxom
 | 
						||
		    utilise Path Info pour spécifier les entrées de blog
 | 
						||
		    en tant que pages d'index, et si un chemin dans
 | 
						||
		    Blosxom existe en tant que fichier statique dans le système de
 | 
						||
		    fichiers, c'est ce dernier qui sera par conséquent privilégié.
 | 
						||
		    Toute requête dont la réponse n'a pas été générée à
 | 
						||
		    l'avance sera traitée par le programme CGI. Cela
 | 
						||
		    signifie que les entrées individuelles comme les
 | 
						||
		    commentaires seront toujours servies par le
 | 
						||
		    programme CGI, et seront donc toujours visibles.
 | 
						||
		    Cette configuration permet aussi de ne pas faire
 | 
						||
		    apparaître le programme CGI Blosxom dans l'URL de la barre
 | 
						||
		    d'adresse. Enfin, mod_rewrite est un module extrêmement
 | 
						||
		    souple et puissant ; prenez le temps de bien
 | 
						||
		    l'étudier afin de parvenir à la configuration qui
 | 
						||
		    correspondra le mieux à votre situation. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
        <section id="caching-content-with-mod_cache">
 | 
						||
            <title>Mise en cache du contenu avec mod_cache
 | 
						||
            </title>
 | 
						||
            <p>Le module mod_cache implémente une mise en cache
 | 
						||
	    intelligente des réponses HTTP : il tient compte des délais
 | 
						||
	    de péremption et des contraintes en matière de contenu
 | 
						||
	    inhérentes à la spécification HTTP. Le module mod_cache met
 | 
						||
	    en cache les URL des contenus des réponses. Si un contenu envoyé au
 | 
						||
	    client peut être mis en cache, il est sauvegardé sur disque.
 | 
						||
	    Les requêtes ultérieures pour cette URL seront alors servies
 | 
						||
	    directement depuis le cache. Le module fournisseur pour
 | 
						||
	    mod_cache, mod_disk_cache, détermine la manière dont les
 | 
						||
	    contenus sont stockés sur disque. La plupart des systèmes de
 | 
						||
	    serveur possèdent plus d'espace disque que de mémoire, et il
 | 
						||
	    est bon de garder à l'esprit que certains noyaux système mettent en
 | 
						||
	    cache de manière transparente en mémoire les contenus sur
 | 
						||
	    disque fréquemment accédés ; il n'est donc pas très utile de
 | 
						||
	    répéter cette opération au niveau du serveur. 
 | 
						||
            </p>
 | 
						||
            <p>Pour mettre en oeuvre une mise en cache de contenu
 | 
						||
	    efficace et éviter de présenter à l'utilisateur un contenu
 | 
						||
	    invalide ou périmé, l'application qui génère le contenu à
 | 
						||
	    jour doit envoyer les en-têtes de réponse corrects. En
 | 
						||
	    effet, en l'absence d'en-têtes comme <code>Etag:</code>,
 | 
						||
	    <code>Last-Modified:</code> ou <code>Expires:</code>,
 | 
						||
	    <module>mod_cache</module> ne sera pas en mesure de décider
 | 
						||
	    de manière appropriée
 | 
						||
	    s'il doit mettre le contenu en cache, s'il doit le servir
 | 
						||
	    directement depuis ce dernier, ou s'il doit tout simplement
 | 
						||
	    ne rien faire. Lorsque vous testerez la mise en cache, vous
 | 
						||
	    devrez peut-être modifier votre application ou, en cas
 | 
						||
	    d'impossibilité, désactiver de manière sélective la mise en
 | 
						||
	    cache des URLs qui posent problème. Les modules mod_cache ne
 | 
						||
	    sont pas compilés par défaut ; pour ce faire, vous devez
 | 
						||
	    utiliser l'option <code>--enable-cache[=shared]</code> du
 | 
						||
	    script configure. Si vous utilisez une distribution binaire
 | 
						||
	    d'Apache httpd, ou si elle fait partie de votre portage ou
 | 
						||
	    de votre sélection de paquets, <module>mod_cache</module>
 | 
						||
	    sera probablement déjà inclus. 
 | 
						||
            </p>
 | 
						||
            
 | 
						||
            
 | 
						||
            <section id="example-wiki">
 | 
						||
                <title>Exemple : wiki.apache.org
 | 
						||
                </title>
 | 
						||
                    <!-- Is this still the case? Maybe we should give
 | 
						||
                        a better example here too.-->
 | 
						||
                <p>
 | 
						||
                    Le Wiki de l'Apache Software Foundation est servi
 | 
						||
		    par MoinMoin. MoinMoin est écrit en Python et
 | 
						||
		    s'exécute en tant que programme CGI. A l'heure
 | 
						||
		    actuelle, toute tentative pour l'exécuter via
 | 
						||
		    mod_python s'est soldée par un échec. Le programme
 | 
						||
		    CGI induit une charge inacceptable sur le serveur,
 | 
						||
		    particulièrement lorsque le Wiki est indexé par des
 | 
						||
		    moteurs de recherche comme Google. Pour alléger la
 | 
						||
		    charge de la machine, l'équipe d'infrastructure
 | 
						||
		    d'Apache s'est tournée vers mod_cache. Il s'est
 | 
						||
		    avéré que <a href="/httpd/MoinMoin">MoinMoin</a>
 | 
						||
		    nécessitait un petit patch pour adopter un
 | 
						||
		    comportement approprié en aval du serveur de mise
 | 
						||
		    en cache : certaines requêtes ne pouvaient jamais
 | 
						||
		    être mises en cache, et les modules Python
 | 
						||
		    concernés ont été mis à jour pour pouvoir envoyer
 | 
						||
		    les en-têtes de réponse HTTP corrects. Après cette
 | 
						||
		    modification, la mise en cache en amont du Wiki a
 | 
						||
		    été activée via l'insertion des lignes suivantes
 | 
						||
		    dans le fichier de configuration
 | 
						||
		    <code>httpd.conf</code> :
 | 
						||
                </p>
 | 
						||
                
 | 
						||
<highlight language="config">
 | 
						||
CacheRoot /raid1/cacheroot
 | 
						||
CacheEnable disk /
 | 
						||
# Une page modifiée il y a 100 minutes expirera dans 10 minutes
 | 
						||
CacheLastModifiedFactor .1
 | 
						||
# Dans tous les cas, vérifier la validité des pages après 6 heures
 | 
						||
CacheMaxExpire 21600
 | 
						||
</highlight>
 | 
						||
                
 | 
						||
                <p>Cette configuration essaie de mettre en cache tout
 | 
						||
		contenu de son serveur virtuel. Elle ne mettra jamais en
 | 
						||
		cache un contenu plus vieux que 6 heures (voir la
 | 
						||
		directive <directive
 | 
						||
		module="mod_cache">CacheMaxExpire</directive>). Si
 | 
						||
		l'en-tête <code>Expires:</code> est absent de la
 | 
						||
		réponse, <module>mod_cache</module> va calculer une date
 | 
						||
		d'expiration en fonction du contenu de l'en-tête
 | 
						||
		<code>Last-Modified:</code>. Le principe de ce calcul
 | 
						||
		qui utilise la directive <directive
 | 
						||
		module="mod_cache">CacheLastModifiedFactor</directive>
 | 
						||
		se base sur l'hypothèse que si une page a été modifiée
 | 
						||
		récemment, il y a de fortes chances pour qu'elle le soit
 | 
						||
		à nouveau dans un futur proche et devra donc être remise
 | 
						||
		en cache. 
 | 
						||
                </p>
 | 
						||
                <p>
 | 
						||
                    Notez qu'il peut s'avérer payant de
 | 
						||
		    <em>désactiver</em> l'en-tête <code>ETag:</code> :
 | 
						||
		    pour les fichiers inférieurs à 1 ko, le serveur
 | 
						||
		    doit calculer la somme de vérification checksum (en
 | 
						||
		    général MD5) et envoyer une réponse <code>304 Not
 | 
						||
		    Modified</code>, ce qui utilise des ressources CPU
 | 
						||
		    et réseau pour le transfert (1 paquet TCP). Pour les
 | 
						||
		    ressources supérieures à 1 ko, les ressources CPU
 | 
						||
		    consommées peuvent devenir importantes car l'en-tête
 | 
						||
		    est calculé à chaque requête. Malheureusement, il
 | 
						||
		    n'existe actuellement aucun moyen pour mettre en
 | 
						||
		    cache ces en-têtes. 
 | 
						||
                </p>
 | 
						||
<highlight language="config">
 | 
						||
<FilesMatch "\.(jpe?g|png|gif|js|css|x?html|xml)">
 | 
						||
    FileETag None
 | 
						||
</FilesMatch>
 | 
						||
</highlight>
 | 
						||
                
 | 
						||
                <p>
 | 
						||
                    Dans l'exemple précédent: la génération d'un en-tête
 | 
						||
		    <code>ETag:</code> sera désactivée pour la plupart
 | 
						||
		    des ressources statiques. Le serveur ne génère pas
 | 
						||
		    ces en-têtes pour les ressources dynamiques. 
 | 
						||
                </p>
 | 
						||
                
 | 
						||
                
 | 
						||
            </section>
 | 
						||
        </section>
 | 
						||
    </section>
 | 
						||
    <section id="further-considerations">
 | 
						||
        <title>Pour aller plus loin
 | 
						||
        </title>
 | 
						||
        <p>Armés du savoir-faire pour personnaliser un système afin
 | 
						||
	qu'il affiche les performances désirées, nous découvrirons vite
 | 
						||
	qu'<em>1</em> sytème à lui seul peut constituer un goulot
 | 
						||
	d'étranglement. A ce sujet, la page du Wiki <a
 | 
						||
	href="http://wiki.apache.org/httpd/PerformanceScalingOut">PerformanceScalingOut</a>
 | 
						||
	décrit comment adapter un système à mesure qu'il prend de
 | 
						||
	l'ampleur, ou comment personnaliser plusieurs systèmes dans leur
 | 
						||
	ensemble.
 | 
						||
        </p>
 | 
						||
    </section>
 | 
						||
</manualpage>
 |