1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head><!--
4 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5 This file is generated from xml source: DO NOT EDIT
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8 <title>mod_unique_id - Serveur Apache HTTP</title>
9 <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
10 <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
11 <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
12 <link href="../images/favicon.ico" rel="shortcut icon" /></head>
14 <div id="page-header">
15 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
16 <p class="apache">Serveur Apache HTTP Version 2.3</p>
17 <img alt="" src="../images/feather.gif" /></div>
18 <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div>
20 <a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">Serveur HTTP</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.3</a> > <a href="./">Modules</a></div>
21 <div id="page-content">
22 <div id="preamble"><h1>Module Apache mod_unique_id</h1>
24 <p><span>Langues Disponibles: </span><a href="../en/mod/mod_unique_id.html" hreflang="en" rel="alternate" title="English"> en </a> |
25 <a href="../fr/mod/mod_unique_id.html" title="Français"> fr </a> |
26 <a href="../ja/mod/mod_unique_id.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> |
27 <a href="../ko/mod/mod_unique_id.html" hreflang="ko" rel="alternate" title="Korean"> ko </a></p>
29 <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Fournit une variable d'environnement contenant un
30 identifiant unique pour chaque requête</td></tr>
31 <tr><th><a href="module-dict.html#Status">Statut:</a></th><td>Extension</td></tr>
32 <tr><th><a href="module-dict.html#ModuleIdentifier">Identificateur de Module:</a></th><td>unique_id_module</td></tr>
33 <tr><th><a href="module-dict.html#SourceFile">Fichier Source:</a></th><td>mod_unique_id.c</td></tr></table>
37 <p>Ce module fournit un identifiant dont l'unicité est garantie
38 parmi "toutes" les requêtes sous des conditions très précises.
39 L'identifiant unique le sera aussi parmi plusieurs machines
40 appartenant à un cluster correctement configuré. L'identifiant est
41 affecté à la variable d'environnement <code>UNIQUE_ID</code> pour
42 chaque requête. Les identifiants uniques sont utiles pour diverses
43 raisons dont la nature se situe au delà de la portée de ce
46 <div id="quickview"><h3 class="directives">Directives</h3>
47 <p>Ce module ne fournit aucune directive.</p>
50 <li><img alt="" src="../images/down.gif" /> <a href="#theory">Théorie</a></li>
52 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
54 <h2><a name="theory" id="theory">Théorie</a></h2>
57 <p>Tout d'abord un bref rappel de la manière dont le serveur Apache
58 fonctionne sous Unix (cette fonctionnalité n'étant actuellement pas
59 supportée sous Windows NT). Sous Unix, Apache crée plusieurs
60 processus enfants, ces derniers traitant les requêtes une par une.
61 Chaque processus enfant peut traiter plusieurs requêtes pendant sa
62 durée de vie. Dans le cadre de cette discussion, nous supposerons
63 que les différents processus enfants ne s'échangent pas de données
64 entre eux. Nous nous référerons aux processus enfants sous le nom de
65 <dfn>processus httpd</dfn>.</p>
67 <p>Votre site web est réparti entre une ou plusieurs machines dont
68 vous êtes l'administrateur, et que nous nommerons cluster de
69 serveurs. Chaque serveur peut exécuter plusieurs instances d'Apache.
70 L'ensemble de ces dernières sera considéré comme "l'Univers", et
71 sous certaines hypothèses, nous montrerons qu'il est possible dans
72 cet univers, de générer des identifiants uniques pour chaque
73 requête, sans pour autant nécessiter une communication importante
74 entre les différents serveurs du cluster.</p>
76 <p>Les machines de votre cluster doivent satisfaire ces conditions
77 (même si le cluster ne comporte qu'une machine, vous devez
78 synchroniser son horloge avec NTP) :</p>
81 <li>Les temps des machines sont synchronisés via NTP ou tout autre
82 protocole de synchronisation du temps en réseau.</li>
84 <li>Les nom d'hôtes des machines sont tous différents, de façon à
85 ce que le module puisse recevoir une adresse IP différente pour
86 chaque machine du cluster en effectuant une recherche sur le nom
90 <p>Au vu des caractéristiques actuelles du système d'exploitation,
91 nous supposerons que les pids (identifiants processus) sont codés
92 sur 32 bits. Si le système d'exploitation utilise plus de 32 bits
93 pour un pid, la correction est triviale mais doit être effectuée
96 <p>Ces hypothèses posées, à un instant donné, nous pouvons
97 distinguer tout processus httpd sur toute machine du cluster de tous
98 les autres processus httpd. Pour ce faire, il suffit d'utiliser
99 l'adresse IP de la machine et le pid du processus httpd. Ainsi, afin
100 de générer des identifiants uniques pour chaque requête, il suffit
101 d'effectuer une distinction en fonction du temps.</p>
103 <p>Pour déterminer le temps, nous utiliserons un repère de temps
104 Unix (les secondes écoulées depuis le 1er janvier 1970 UTC), et un
105 compteur 16 bits. La précision du repère de temps n'étant que d'une
106 seconde, le compteur va représenter 65536 valeurs par seconde. Le
107 quadruplet <em>(adresse IP, pid, repère de temps, compteur)</em> est
108 en mesure de distinguer 65536 requêtes par seconde par processus
109 httpd. Il peut cependant arriver que le même pid soit réutilisé au
110 cours du temps, et le compteur est là pour pallier cet
113 <p>Lorsqu'un processus enfant httpd est créé, le compteur est
114 initialisé avec (nombre de microsecondes actuel divisé par 10)
115 modulo 65536 (cette formule a été choisie pour éliminer certains
116 problème de variance avec les bits de poids faibles du compteur de
117 microsecondes sur certains systèmes). Lorsqu'un identifiant unique
118 est généré, le repère de temps utilisé est le moment où la requête
119 arrive sur le serveur web. Le compteur est incrémenté à chaque
120 création d'identifiant (et peut repasser à 0 lorsqu'il a atteint sa
121 valeur maximale).</p>
123 <p>Le noyau génère un pid pour chaque processus lors de sa création,
124 et le compteur de pid est réinitialisé à une certaine valeur
125 lorsqu'il a atteint sa valeur maximale (les pid sont codés sur 16
126 bits sous de nombreux Unixes, mais les systèmes les plus récents les
127 ont étendus à 32 bits). La même valeur de pid pourra donc être
128 réutilisée au cours du temps. Cependant, tant qu'elle n'est pas
129 réutilisée dans la même seconde, elle ne remet pas en cause
130 l'unicité de notre quadruplet. Nous supposerons donc que le système
131 ne créera pas plus de 65536 processus en une seconde (ce nombre peut
132 être de 32768 sous certains Unixes, mais même dans ce cas, on est en
133 général loin de cette situation).</p>
135 <p>Il est possible que le temps se répète pour une raison
137 Supposons par exemple que l'horloge système soit retardée et repasse
138 par un temps passé (ou bien, comme elle avançait, elle a été remise
139 à l'heure, et elle repasse par un temps futur). Dans ce cas, il peut
140 être facilement démontré que le couple pid/repère de temps peut être
141 réutilisé. Le choix de la formule d'initialisation du compteur a
142 été effectué dans l'intention de pallier ce problème. Notez qu'un
143 nombre vraiment aléatoire serait souhaitable pour initialiser le
144 compteur, mais il n'existe pas de tel nombre directement lisible sur
145 la plupart des systèmes (c'est à dire que vous ne pouvez pas
146 utiliser rand() car vous devez déclencher le générateur avec une
147 valeur unique, et vous ne pouvez pas utiliser le temps à cet effet
148 car celui-ci , au moins à la seconde près, s'est répété). Il ne
149 s'agit donc pas d'une défense parfaite.</p>
151 <p>Même si elle n'est pas parfaite, quel est le degré d'efficacité
152 de cette défense ? Supposons
153 qu'une de vos machines serve au plus 500 requêtes par seconde (ce
154 qui constitue une limite supérieure très raisonnable au moment où ce
155 document est écrit, car les systèmes ne se contentent en général pas
156 de débiter des fichiers statiques). Pour y parvenir, un certain nombre
157 de processus enfants sera nécessaire, qui dépendra du nombre de
158 clients simultanés présents. Mais soyons pessimiste et supposons
159 qu'un seul processus enfant soit capable de servir 500 requêtes par
161 Il existe 1000 valeurs de démarrage possibles du compteur pour
162 lesquelles deux séquences de 500 requêtes puissent se recouvrir. Il
163 y a donc 1,5% de chance que le processus enfant répète une valeur de
164 compteur si le temps se répète (avec une résolution d'une seconde),
165 et l'unicité sera alors remise en cause. C'est cependant un exemple
166 très pessimiste, et avec les valeurs du monde réel, il y a bien
167 moins de chances que cela ne se produise. Si vous estimez que ceci a
168 tout de même quelque chances de se produire sur votre système, vous
169 pouvez migrer vers un compteur à 32 bits (en modifiant le code).</p>
171 <p>On pourrait supposer que ceci a plus de chance de se produire
172 lors du passage à l'heure d'hiver où l'horloge est "retardée". Cela
173 ne constitue cependant pas un problème car les temps pris en compte
174 ici sont des temps UTC, qui vont "toujours" de l'avant. Notez que
175 les Unixes à base de processeur x86 peuvent nécessiter une
176 configuration particulière pour que ceci soit vrai -- il doivent
177 être configurés pour assumer que l'horloge système est en UTC et
178 compenser de manière appropriée. Mais même dans ce cas, si vous
179 utilisez NTP, votre temps UTC sera correct peu après le
182 <p>La variable d'environnement <code>UNIQUE_ID</code> est construite
183 par codage du quadruplet de 112 bits (adresse IP sur 32 bits, pid
184 sur 32 bits, repère de temps sur 32 bits et compteur 16 bits) en
185 utilisant l'alphabet <code>[A-Za-z0-9@-]</code> d'une manière
186 similaire à celle du codage MIME base64, et sa valeur se présente
187 sous la forme d'une chaîne de 19 caractères. L'alphabet MIME base64
188 est en fait <code>[A-Za-z0-9+/]</code> ; cependant, les caractères
189 <code>+</code> et <code>/</code> nécessitent un codage particulier
190 dans les URLs, ce qui rend leur utilisation peu commode. Toutes les
191 valeurs sont codées dans l'ordre des octets d'une adresse réseau de
193 que le codage soit comparable entre des architectures où l'ordre des
194 octets est différent. L'ordre réel de codage est : repère de temps,
195 adresse IP, pid, compteur. Cet ordre de codage possède un but
196 précis, mais il faut souligner que les applications n'ont aucun
197 intérêt à entrer dans les détails de ce codage. Les applications
198 doivent se contenter de traiter la variable <code>UNIQUE_ID</code>
199 comme un symbole opaque, qui peut être comparé avec d'autres
200 <code>UNIQUE_ID</code>s en ne testant que leur égalité.</p>
202 <p>L'ordre a été choisi de façon à ce qu'il soit possible de
203 modifier le codage dans le futur sans avoir à se préoccuper de
204 conflits éventuels avec une base de données de
205 <code>UNIQUE_ID</code>s existante. Les nouveaux codages doivent
206 conserver le repère de temps comme premier élément, et pour le
207 reste, utiliser les même alphabet et longueur en bits. Comme les
208 repères de temps constituent essentiellement un séquence croissante,
209 il suffit que toutes les machines du cluster arrêtent de servir et
210 de requérir dans la même <em>seconde repère</em>, et n'utilisent
211 alors plus l'ancien format de codage. Ensuite, elles peuvent
212 reprendre le traitement des requêtes en utilisant les nouveaux
215 <p>Nous pensons que ceci apporte une solution relativement portable
216 au problème. Elle peut être étendue aux systèmes multithreadés comme
217 Windows NT, et peut évoluer en fonction des besoins futurs. Les
218 identifiants générés possèdent une durée de vie pratiquement infinie
219 car les identifiants futurs pourront être allongés selon les
220 besoins. Pratiquement aucune communication n'est requise entre les
221 machines du cluster (seule la synchronisation NTP est requise, ce
222 qui représente une charge très faible), et aucune communication
223 entre les processus httpd n'est nécessaire (la communication est
224 implicite et incluse dans le pid assigné par le noyau). Dans des
225 situations très spécifiques, l'identifiant peut être raccourci, mais
226 dans ce cas, d'avantage d'informations doivent être admises (par
227 exemple, les 32 bits de l'adresse IP sont excessifs pour la plupart
228 des sites, mais il n'existe pas de valeur de remplacement portable
232 <div class="bottomlang">
233 <p><span>Langues Disponibles: </span><a href="../en/mod/mod_unique_id.html" hreflang="en" rel="alternate" title="English"> en </a> |
234 <a href="../fr/mod/mod_unique_id.html" title="Français"> fr </a> |
235 <a href="../ja/mod/mod_unique_id.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> |
236 <a href="../ko/mod/mod_unique_id.html" hreflang="ko" rel="alternate" title="Korean"> ko </a></p>
237 </div><div id="footer">
238 <p class="apache">Copyright 2010 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
239 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div>