]> granicus.if.org Git - apache/blob - docs/manual/mod/event.xml.fr
Rebuild.
[apache] / docs / manual / mod / event.xml.fr
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
4 <!-- English Revision: 1742029 -->
5 <!-- French translation : Lucien GENTIS -->
6 <!-- Reviewed by : Vincent Deffontaines -->
7
8 <!--
9  Licensed to the Apache Software Foundation (ASF) under one or more
10  contributor license agreements.  See the NOTICE file distributed with
11  this work for additional information regarding copyright ownership.
12  The ASF licenses this file to You under the Apache License, Version 2.0
13  (the "License"); you may not use this file except in compliance with
14  the License.  You may obtain a copy of the License at
15
16      http://www.apache.org/licenses/LICENSE-2.0
17
18  Unless required by applicable law or agreed to in writing, software
19  distributed under the License is distributed on an "AS IS" BASIS,
20  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  See the License for the specific language governing permissions and
22  limitations under the License.
23 -->
24
25 <modulesynopsis metafile="event.xml.meta">
26 <name>event</name>
27 <description>Une variante du MPM <module>worker</module> conçue pour ne
28 mobiliser des threads que pour les connexions en cours de traitement</description>
29 <status>MPM</status>
30 <sourcefile>event.c</sourcefile>
31 <identifier>mpm_event_module</identifier>
32
33 <summary>
34     <p>Le module multi-processus (MPM) <module>event</module> est, comme son nom
35     l'indique, une implémentation asynchrone basée sur les évènements et conçu
36     pour permettre le traitement d'un nombre accru de requêtes
37     simultanées en déléguant certaines tâches
38     aux threads d'écoute, libérant par là-même les
39     threads de travail et leur permettant de traiter les nouvelles requêtes.</p>
40
41     <p>Pour utiliser le MPM <module>event</module>, ajoutez
42     <code>--with-mpm=event</code> aux arguments du script
43     <program>configure</program> lorsque vous compilez le programme
44     <program>httpd</program>.</p>
45
46 </summary>
47
48 <seealso><a href="worker.html">Le MPM worker</a></seealso>
49
50 <section id="event-worker-relationship"><title>Relations avec le MPM Worker</title>
51 <p>Le MPM <module>event</module> s'inspire du MPM <module>worker</module> qui
52 implémente un serveur hybride multi-processus et multi-threads. Un processus de
53 contrôle unique (le parent) est chargé de lancer des processus enfants. Chaque
54 processus enfant crée un nombre de threads serveurs défini via la directive
55 <directive module="mpm_common">ThreadsPerChild</directive>, ainsi qu'un thread
56 d'écoute qui surveille les requêtes entrantes et les distribue aux threads de
57 travail pour traitement au fur et à mesure de leur arrivée.</p>
58
59 <p>Les directives de configuration à l'exécution sont identiques à celles que
60 propose le MPM <module>worker</module>, avec l'unique addition de la directive
61 <directive>AsyncRequestWorkerFactor</directive>.</p>
62
63 </section>
64
65 <section id="how-it-works"><title>Comment tout cela fonctionne</title>
66     
67     <p>Ce module MPM a été conçu à l'origine pour résoudre le "problème keep
68     alive" de HTTP. Lorsqu'un client a effectué une première requête, il peut
69     garder la connexion ouverte et envoyer les requêtes suivante en utilisant le
70     même socket, ce qui diminue considérablement la charge qui aurait été
71     induite par la création de nouvelles connexions TCP. Cependant, le
72     fonctionnement du serveur HTTP Apache impose de réserver un couple processus
73     enfant/thread pour attendre les données en provenance du client, ce qui
74     présente certains inconvénients. Pour résoudre ce problème, le MPM Event
75     utilise un thread d'écoute dédié pour chaque processus associé à un jeu de
76     threads de travail, partageant les files d'attentes spécifiques aux
77     requêtes en mode keep-alive (ou plus simplement en mode "lisible"), à celles
78     en mode écriture des résultats, et à celles en court de fermeture
79     ("closing"). Une boucle d'attente d'évènements déclenchée en fonction du
80     statut de la disponibilité du socket ajuste ces files d'attente et distribue
81     le travail au jeu de threads de travail.
82     </p>
83
84     <p>Cette nouvelle architecture, en exploitant les sockets non blocants et
85     les fonctionnalités des noyaux modernes mis en valeur par
86     <glossary>APR</glossary> (comme epoll de Linux), n'a plus besoin du
87     <directive module="core">Mutex</directive> <code>mpm-accept</code> pour
88     éviter le problème de "thundering herd".</p>
89
90     <p>La directive <directive>AsyncRequestWorkerFactor</directive> permet de
91     définir le nombre total de connexions qu'un bloc processus/thread peut
92     gérer.</p>
93
94     <section id="async-connections"><title>Connexions asynchrones</title>
95         <p>Avec les MPM précédents, les connexions asynchrones nécessitaient
96         un thread de travail dédié, mais ce n'est plus le cas avec le MPM Event.
97         La page d'état de <module>mod_status</module> montre de nouvelles
98         colonnes dans la section "Async connections" :</p>
99         <dl>
100             <dt>Writing</dt>
101             <dd>Lors de l'envoi de la réponse au client, il peut arriver que le
102             tampon d'écriture TCP soit plein si la connexion est trop lente. Si
103             cela se produit, une instruction <code>write()</code> vers le socket
104             renvoie en général <code>EWOULDBLOCK</code> ou <code>EAGAIN</code>
105             pour que l'on puisse y écrire à nouveau après un certain temps
106             d'inactivité. Le thread de travail qui utilise le socket doit alors
107             être en mesure de récupérer la tâche en attente et la restituer au
108             thread d'écoute qui, à son tour, la réattribuera au premier thread
109             de travail disponible, lorsqu'un évènement sera généré pour le socket
110             (par exemple, "il est maintenant possible d'écrire dans le socket").
111             Veuillez vous reporter à la section à propos des limitations pour
112             plus de détails.
113             </dd>
114
115             <dt>Keep-alive</dt>
116             <dd>La gestion des connexions persistantes constitue la principale
117             amélioration par rapport au MPM Worker. Lorsqu'un thread de travail
118             a terminé l'envoi d'une réponse à un client, il peut restituer la
119             gestion du socket au thread d'écoute, qui à son tour va attendre un
120             évènement en provenance du système d'exploitation comme "le socket
121             est lisible". Si une nouvelle requête arrive en provenance du
122             client, le thread d'écoute l'attribuera au premier thread de travail
123             disponible. Inversement, si le délai <directive
124             module="core">KeepAliveTimeout</directive> est atteint, le socket
125             sera fermé par le thread d'écoute. Les threads de travail n'ont
126             donc plus à s'occuper des sockets inactifs et ils peuvent être
127             réutilisés pour traiter d'autres requêtes.</dd>
128
129             <dt>Closing</dt>
130             <dd>Parfois, le MPM doit effectuer une fermeture progressive, c'est
131             à dire envoyer au client une erreur survenue précédemment alors que
132             ce dernier est en train de transmettre des données à httpd. Envoyer la réponse et
133             fermer immédiatement la connexion n'est pas une bonne solution car
134             le client (qui est encore en train d'envoyer le reste de la requête)
135             verrait sa connexion réinitialisée et ne pourrait pas lire la
136             réponse de httpd. Si cela se produit, httpd essaie donc de lire le
137             reste de la requête afin de permettre au client de lire la réponse
138             entièrement. La fermeture progressive est limitée dans le temps,
139             mais elle peut tout de même être assez longue, si bien qu'il est
140             intéressant qu'un thread de travail puisse se décharger de cette
141             tâche sur le thread d'écoute.</dd>
142         </dl>
143
144         <p>Ces améliorations sont disponible pour les connexions HTTP ou HTTPS.</p> 
145
146     </section>
147
148     <section id="limitations"><title>Limitations</title>
149         <p>La gestion améliorée des connexions peut ne pas fonctionner pour
150         certains filtres de connexion qui se sont déclarés eux-mêmes
151         incompatibles avec le MPM Event. Dans ce cas, le MPM Event réadoptera le
152         comportement du MPM <module>worker</module> et réservera un thread de
153         travail par connexion. Notez que tous les modules inclus dans la
154         distribution du serveur httpd sont compatibles avec le MPM Event.</p>
155
156         <p>Une restriction similaire apparaît lorsqu'une requête utilise un
157         filtre en sortie qui doit pouvoir lire et/ou modifier la totalité du
158         corps de la réponse. Si la connexion avec le client se bloque pendant
159         que le filtre traite les données, et si la quantité de données produites
160         par le filtre est trop importante pour être stockée en mémoire, le
161         thread utilisé pour la requête n'est pas libéré pendant que httpd attend
162         que les données soient transmises au client.<br /> 
163         Pour illustrer ce cas de figure, nous pouvons envisager les deux
164         situations suivantes : servir une ressource statique (comme un fichier
165         CSS) ou servir un contenu issu d'un programme FCGI/CGI ou d'un serveur
166         mandaté. La première situation est prévisible ; en effet, le MPM Event a
167         une parfaite visibilité sur la fin du contenu, et il peut utiliser les
168         évènements : le thread de travail qui sert la réponse peut envoyer les
169         premiers octets jusqu'à ce que <code>EWOULDBLOCK</code> ou
170         <code>EAGAIN</code> soit renvoyé, et déléguer le reste de la réponse au thread
171         d'écoute. Ce dernier en retour attend un évènement sur le socket, et
172         délègue le reste de la réponse au premier
173         thread de travail disponible. Dans la deuxième situation par contre
174         (FCGI/CGI/contenu mandaté), le MPM n'a pas de visibilité sur la fin de
175         la réponse, et le thread de travail doit terminer sa tâche avant de
176         rendre le contrôle au thread d'écoute. La seule solution consisterait
177         alors à stocker la réponse en mémoire, mais ce ne serait pas l'option la
178         plus sure en matière de stabilité du serveur et d'empreinte mémoire.
179         </p>
180
181     </section>
182
183     <section id="background"><title>Matériel d'arrière-plan</title>
184         <p>Le modèle event a été rendu possible par l'introduction de nouvelles
185         APIs dans les systèmes d'exploitation supportés :</p>
186         <ul>
187             <li>epoll (Linux) </li>
188             <li>kqueue (BSD) </li>
189             <li>event ports (Solaris) </li>
190         </ul>
191         <p>Avant que ces APIs soient mises à disposition, les APIs
192         traditionnelles <code>select</code> et <code>poll</code> devaient être
193         utilisées. Ces APIs deviennent lentes si on les utilise pour gérer de
194         nombreuses connexions ou si le jeu de connexions possède un taux de
195         renouvellement élevé. Les nouvelles APIs permettent de gérer beaucoup
196         plus de connexions et leur performances sont meilleures lorsque le jeu
197         de connexions à gérer change fréquemment. Ces APIs ont donc rendu
198         possible l'écriture le MPM Event qui est mieux adapté à la situation
199         HTTP typique où de nombreuses connexions sont inactives.</p>
200
201         <p>Le MPM Event suppose que l'implémentation de <code>apr_pollset</code>
202         sous-jacente est raisonnablement sure avec l'utilisation des threads
203         (threadsafe). Ceci évite au MPM de devoir effectuer trop verrouillages
204         de haut niveau, ou d'avoir à réveiller le thread d'écoute pour lui
205         envoyer un socket keep-alive. Ceci n'est possible qu'avec KQueue et
206         EPoll.</p>
207
208     </section>
209         
210 </section>
211
212 <section id="requirements"><title>Prérequis</title>
213     <p>Ce MPM dépend des opérations atomiques compare-and-swap
214     d'<glossary>APR</glossary> pour la synchronisation des threads. Si
215     vous compilez pour une plate-forme x86 et n'avez pas besoin du
216     support 386, ou si vous compilez pour une plate-forme SPARC et
217     n'avez pas besoin du support pre-UltraSPARC, ajoutez
218     <code>--enable-nonportable-atomics=yes</code> aux arguments du
219     script <program>configure</program>. Ceci permettra à APR
220     d'implémenter les opérations atomiques en utilisant des instructions
221     performantes indisponibles avec les processeurs plus
222     anciens.</p>
223
224     <p>Ce MPM ne fonctionne pas de manière optimale sur les
225     plates-formes plus anciennes qui ne gèrent pas correctement les
226     threads, mais ce problème est sans objet du fait du prérequis
227     concernant EPoll ou KQueue.</p>
228
229     <ul>
230
231       <li>Pour utiliser ce MPM sous FreeBSD, la version 5.3 ou
232       supérieure de ce système est recommandée. Il est cependant
233       possible d'exécuter ce MPM sous FreeBSD 5.2.1 si vous utilisez
234       <code>libkse</code> (voir <code>man libmap.conf</code>).</li>
235
236       <li>Pour NetBSD, il est recommander d'utiliser la version 2.0 ou
237       supérieure.</li>
238
239       <li>Pour Linux, un noyau 2.6 est recommandé. Il faut aussi
240       s'assurer que votre version de <code>glibc</code> a été compilée
241       avec le support pour EPoll.</li>
242
243     </ul>
244 </section>
245
246 <directivesynopsis location="mpm_common"><name>CoreDumpDirectory</name>
247 </directivesynopsis>
248 <directivesynopsis location="mpm_common"><name>EnableExceptionHook</name>
249 </directivesynopsis>
250 <directivesynopsis location="mod_unixd"><name>Group</name>
251 </directivesynopsis>
252 <directivesynopsis location="mpm_common"><name>Listen</name>
253 </directivesynopsis>
254 <directivesynopsis location="mpm_common"><name>ListenBacklog</name>
255 </directivesynopsis>
256 <directivesynopsis location="mpm_common"><name>SendBufferSize</name>
257 </directivesynopsis>
258 <directivesynopsis location="mpm_common"><name>MaxRequestWorkers</name>
259 </directivesynopsis>
260 <directivesynopsis location="mpm_common"><name>MaxMemFree</name>
261 </directivesynopsis>
262 <directivesynopsis location="mpm_common"><name>MaxConnectionsPerChild</name>
263 </directivesynopsis>
264 <directivesynopsis location="mpm_common"><name>MaxSpareThreads</name>
265 </directivesynopsis>
266 <directivesynopsis location="mpm_common"><name>MinSpareThreads</name>
267 </directivesynopsis>
268 <directivesynopsis location="mpm_common"><name>PidFile</name>
269 </directivesynopsis>
270 <directivesynopsis location="mpm_common"><name>ScoreBoardFile</name>
271 </directivesynopsis>
272 <directivesynopsis location="mpm_common"><name>ServerLimit</name>
273 </directivesynopsis>
274 <directivesynopsis location="mpm_common"><name>StartServers</name>
275 </directivesynopsis>
276 <directivesynopsis location="mpm_common"><name>ThreadLimit</name>
277 </directivesynopsis>
278 <directivesynopsis location="mpm_common"><name>ThreadsPerChild</name>
279 </directivesynopsis>
280 <directivesynopsis location="mpm_common"><name>ThreadStackSize</name>
281 </directivesynopsis>
282 <directivesynopsis location="mod_unixd"><name>User</name>
283 </directivesynopsis>
284
285 <directivesynopsis>
286 <name>AsyncRequestWorkerFactor</name>
287 <description>Limite le nombre de connexions simultanées par thread</description>
288 <syntax>AsyncRequestWorkerFactor <var>facteur</var></syntax>
289 <default>2</default>
290 <contextlist><context>server config</context> </contextlist>
291 <compatibility>Disponible depuis la version 2.3.13</compatibility>
292
293 <usage>
294     <p>Le MPM event gère certaines connexions de manière asynchrone ;
295     dans ce cas, les threads traitant la requête sont alloués selon les
296     besoins et pour de courtes périodes. Dans les autres cas, un
297     thread est réservé par
298     connexion. Ceci peut conduire à des situations où tous les threads
299     sont saturés et où aucun thread n'est capable d'effectuer de
300     nouvelles tâches pour les connexions asynchrones établies.</p>
301
302     <p>Pour minimiser les effets de ce problème, le MPM event utilise
303     deux méthodes :</p>
304     <ul>
305         <li>il limite le nombre de connexions
306             simultanées par thread en fonction du nombre de processus
307             inactifs;</li>
308         <li>si tous les processus sont occupés, il ferme des connexions
309         permanentes, même si la limite de durée de la connexion n'a
310         pas été atteinte. Ceci autorise les clients
311         concernés à se reconnecter à un autre processus
312         possèdant encore des threads disponibles.</li>
313     </ul>
314
315     <p>Cette directive permet de personnaliser finement la limite du
316     nombre de connexions par thread. Un <strong>processus</strong> n'acceptera de
317     nouvelles connexions que si le nombre actuel de connexions (sans
318     compter les connexions à l'état "closing") est
319     inférieur à :</p>
320
321     <p class="indent"><strong>
322         <directive module="mpm_common">ThreadsPerChild</directive> +
323         (<directive>AsyncRequestWorkerFactor</directive> *
324         <var>nombre de threads inactifs</var>)
325     </strong></p>
326
327     <p>Il est possible d'effectuer une estimation du nombre maximum de
328     connexions simultanées pour tous les processus et pour un nombre donné moyen
329     de threads de travail inactifs comme suit :
330     </p>
331
332
333     <p class="indent"><strong>
334         (<directive module="mpm_common">ThreadsPerChild</directive> +
335         (<directive>AsyncRequestWorkerFactor</directive> *
336         <var>number of idle workers</var>)) * 
337         <directive module="mpm_common">ServerLimit</directive>
338     </strong></p>
339
340     <note><title>Exemple</title>
341     <highlight language="config">
342
343 ThreadsPerChild = 10
344 ServerLimit = 4
345 AsyncRequestWorkerFactor = 2
346 MaxRequestWorkers = 40
347
348 idle_workers = 4 (moyenne pour tous les processus pour faire simple)
349
350 max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
351                 = (10 + (2 * 4)) * 4 = 72
352     
353     </highlight>
354     </note>
355
356     <p>Lorsque tous les threads de travail sont inactifs, le nombre maximum
357     absolu de connexions simultanées peut être calculé de manière plus simple :</p>
358
359     <p class="indent"><strong>
360         (<directive>AsyncRequestWorkerFactor</directive> + 1) *
361         <directive module="mpm_common">MaxRequestWorkers</directive>
362     </strong></p>
363
364     <note><title>Exemple</title>
365     <highlight language="config">
366     
367 ThreadsPerChild = 10 
368 ServerLimit = 4
369 MaxRequestWorkers = 40
370 AsyncRequestWorkerFactor = 2 
371     
372     </highlight>
373
374     <p>Si tous les threads de tous les processus sont inactifs, alors :</p>
375
376     <highlight language="config">idle_workers = 10</highlight>
377
378     <p>Nous pouvons calculer le nombre maximum absolu de connexions simultanées
379     de deux manières :</p>
380     
381     <highlight language="config">
382     
383 max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
384                 = (10 + (2 * 10)) * 4 = 120
385     
386 max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers 
387                 = (2 + 1) * 40 = 120
388     
389     </highlight>
390     </note>
391
392     <p>Le réglage de la directive
393     <directive>AsyncRequestWorkerFactor</directive> nécessite de connaître le
394     trafic géré par httpd pour chaque style d'utilisation spécifique ; si vous
395     modifiez la valeur par défaut, vous devrez par conséquent effectuer des
396     tests approfondis en vous appuyant étroitement sur les données fournies par
397     <module>mod_status</module>.</p>
398
399     <p>La directive <directive
400     module="mpm_common">MaxRequestWorkers</directive> se nommait
401     <directive>MaxClients</directive> avant la version 2.3.13. La valeur
402     ci-dessus montre que cet ancien nom ne correspondait pas à sa
403     signification exacte pour le MPM event.</p>
404
405     <p>La directive <directive>AsyncRequestWorkerFactor</directive>
406     accepte des valeurs d'argument de type non entier, comme "1.5".</p>
407
408 </usage>
409
410 </directivesynopsis>
411
412 </modulesynopsis>