| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd"> | |
| <?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?> | |
| <!-- English Revision: 1939342 --> | |
| <!-- French translation : Lucien GENTIS --> | |
| <!-- Reviewed by : Vincent Deffontaines --> | |
| <!-- | |
| Licensed to the Apache Software Foundation (ASF) under one or more | |
| contributor license agreements. See the NOTICE file distributed with | |
| this work for additional information regarding copyright ownership. | |
| The ASF licenses this file to You under the Apache License, Version 2.0 | |
| (the "License"); you may not use this file except in compliance with | |
| the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| --> | |
| <modulesynopsis metafile="event.xml.meta"> | |
| <name>event</name> | |
| <description>Une variante du MPM <module>worker</module> conçue pour ne | |
| mobiliser des threads que pour les connexions en cours de traitement</description> | |
| <status>MPM</status> | |
| <sourcefile>event.c</sourcefile> | |
| <identifier>mpm_event_module</identifier> | |
| <summary> | |
| <p>Le module multi-processus (MPM) <module>event</module> est, comme son nom | |
| l'indique, une implémentation asynchrone basée sur les évènements et conçu | |
| pour permettre le traitement d'un nombre accru de requêtes | |
| simultanées en déléguant certaines tâches | |
| aux threads d'écoute, libérant par là-même les | |
| threads de travail et leur permettant de traiter les nouvelles requêtes.</p> | |
| <p>Pour utiliser le MPM <module>event</module>, ajoutez | |
| <code>--with-mpm=event</code> aux arguments du script | |
| <program>configure</program> lorsque vous compilez le programme | |
| <program>httpd</program>.</p> | |
| <p>Lorsque ce module est construit en tant que module DSO, il peut être | |
| chargé à l’aide de la commande :</p> | |
| <highlight language="config"> | |
| LoadModule mpm_event_module modules/mod_mpm_event.so | |
| </highlight> | |
| </summary> | |
| <seealso><a href="../mpm.html">Modules multi-processus (MPMs)</a></seealso> | |
| <seealso><a href="worker.html">Le MPM worker</a></seealso> | |
| <section id="event-worker-relationship"><title>Relations avec le MPM Worker</title> | |
| <p>Le MPM <module>event</module> s'inspire du MPM <module>worker</module> qui | |
| implémente un serveur hybride multi-processus et multi-threads. Un processus de | |
| contrôle unique (le parent) est chargé de lancer des processus enfants. Chaque | |
| processus enfant crée un nombre de threads serveurs défini via la directive | |
| <directive module="mpm_common">ThreadsPerChild</directive>, ainsi qu'un thread | |
| d'écoute qui surveille les requêtes entrantes et les distribue aux threads de | |
| travail pour traitement au fur et à mesure de leur arrivée.</p> | |
| <p>Les directives de configuration à l'exécution sont identiques à celles que | |
| propose le MPM <module>worker</module>, avec l'unique addition de la directive | |
| <directive>AsyncRequestWorkerFactor</directive>.</p> | |
| </section> | |
| <section id="how-it-works"><title>Comment tout cela fonctionne</title> | |
| <p>Ce module MPM a été conçu à l'origine pour résoudre le "problème keep | |
| alive" de HTTP. Lorsqu'un client a effectué une première requête, il peut | |
| garder la connexion ouverte et envoyer les requêtes suivantes en utilisant le | |
| même socket, ce qui diminue considérablement la charge qui aurait été | |
| induite par la création de nouvelles connexions TCP. Cependant, le | |
| fonctionnement du serveur HTTP Apache impose de réserver un couple processus | |
| enfant/thread pour attendre les données en provenance du client, ce qui | |
| présente certains inconvénients. Pour résoudre ce problème, le MPM Event | |
| utilise un thread d'écoute dédié pour chaque processus associé à un jeu de | |
| threads de travail, partageant les files d'attentes spécifiques aux | |
| requêtes en mode keep-alive (ou plus simplement en mode "lisible"), à celles | |
| en mode écriture des résultats, et à celles en court de fermeture | |
| ("closing"). Une boucle d'attente d'évènements déclenchée en fonction du | |
| statut de la disponibilité du socket ajuste ces files d'attente et distribue | |
| le travail au jeu de threads de travail. | |
| </p> | |
| <p>Cette nouvelle architecture, en exploitant les sockets non blocants et | |
| les fonctionnalités des noyaux modernes mis en valeur par | |
| <glossary>APR</glossary> (comme epoll de Linux), n'a plus besoin du | |
| <directive module="core">Mutex</directive> <code>mpm-accept</code> pour | |
| éviter le problème de "thundering herd".</p> | |
| <p>La directive <directive>AsyncRequestWorkerFactor</directive> permet de | |
| définir le nombre total de connexions qu'un bloc processus/thread peut | |
| gérer.</p> | |
| <section id="async-connections"><title>Connexions asynchrones</title> | |
| <p>Avec les MPM précédents, les connexions asynchrones nécessitaient | |
| un thread de travail dédié, mais ce n'est plus le cas avec le MPM Event. | |
| La page d'état de <module>mod_status</module> montre de nouvelles | |
| colonnes dans la section "Async connections" :</p> | |
| <dl> | |
| <dt>Writing</dt> | |
| <dd>Lors de l'envoi de la réponse au client, il peut arriver que le | |
| tampon d'écriture TCP soit plein si la connexion est trop lente. Si | |
| cela se produit, une instruction <code>write()</code> vers le socket | |
| renvoie en général <code>EWOULDBLOCK</code> ou <code>EAGAIN</code> | |
| pour que l'on puisse y écrire à nouveau après un certain temps | |
| d'inactivité. Le thread de travail qui utilise le socket doit alors | |
| être en mesure de récupérer la tâche en attente et la restituer au | |
| thread d'écoute qui, à son tour, la réattribuera au premier thread | |
| de travail disponible, lorsqu'un évènement sera généré pour le socket | |
| (par exemple, "il est maintenant possible d'écrire dans le socket"). | |
| Veuillez vous reporter à la section à propos des limitations pour | |
| plus de détails. | |
| </dd> | |
| <dt>Keep-alive</dt> | |
| <dd>La gestion des connexions persistantes constitue la principale | |
| amélioration par rapport au MPM Worker. Lorsqu'un thread de travail | |
| a terminé l'envoi d'une réponse à un client, il peut restituer la | |
| gestion du socket au thread d'écoute, qui à son tour va attendre un | |
| évènement en provenance du système d'exploitation comme "le socket | |
| est lisible". Si une nouvelle requête arrive en provenance du | |
| client, le thread d'écoute l'attribuera au premier thread de travail | |
| disponible. Inversement, si le délai <directive | |
| module="core">KeepAliveTimeout</directive> est atteint, le socket | |
| sera fermé par le thread d'écoute. Les threads de travail n'ont | |
| donc plus à s'occuper des sockets inactifs et ils peuvent être | |
| réutilisés pour traiter d'autres requêtes.</dd> | |
| <dt>Closing</dt> | |
| <dd>Parfois, le MPM doit effectuer une fermeture progressive, c'est | |
| à dire envoyer au client une erreur survenue précédemment alors que | |
| ce dernier est en train de transmettre des données à httpd. Envoyer la réponse et | |
| fermer immédiatement la connexion n'est pas une bonne solution car | |
| le client (qui est encore en train d'envoyer le reste de la requête) | |
| verrait sa connexion réinitialisée et ne pourrait pas lire la | |
| réponse de httpd. | |
| La fermeture progressive est limitée dans le temps, | |
| mais elle peut tout de même être assez longue, si bien qu'elle est | |
| confiée à un thread de travail (y compris les procédures d'arrêt et | |
| la fermeture effective du socket). A partir de la version 2.4.28, | |
| c'est aussi le cas lorsque des connexions finissent par dépasser | |
| leur délai d'attente (le thread d'écoute ne gère jamais les | |
| connexions, si ce n'est attendre et dispatcher les évènements | |
| qu'elles génèrent).</dd> | |
| </dl> | |
| <p>Ces améliorations sont disponible pour les connexions HTTP ou HTTPS.</p> | |
| <p>Les états de connexions ci-dessus sont gérés par le thread d'écoute | |
| via des files d'attente dédiées qui, jusqu'à la version 2.4.27, étaient | |
| lues toutes les 100ms pour déterminer quelles connexions avaient atteint | |
| des limites de durées définies comme <directive | |
| module="mpm_common">Timeout</directive> et <directive | |
| module="core">KeepAliveTimeout</directive>. C'était une solution simple | |
| et efficace mais qui présentait un inconvénient : ces lectures | |
| régulières forçaient le thread d'écoute à se réveiller, souvent sans | |
| nécessité (alors qu'il était totalement inactif), ce qui consommait des | |
| ressources pour rien. A partir de la version 2.4.28, ces files d'attente | |
| sont entièrement gérées selon une logique basées sur les évènements, et | |
| ne font donc plus l'objet d'une lecture systématique. Les environnements | |
| aux ressources limitées, comme les serveurs embarqués, seront les plus | |
| grands bénéficiaires de cette amélioration.</p> | |
| </section> | |
| <section id="graceful-close"><title>Arrêt de processus en douceur et | |
| utilisation du scoreboard</title> | |
| <p>Ce MPM présentait dans le passé des limitations de montée en | |
| puissance qui | |
| provoquaient l'erreur suivante : "<strong>scoreboard is full, not at | |
| MaxRequestWorkers</strong>". La directive <directive | |
| module="mpm_common">MaxRequestWorkers</directive> permet de limiter le | |
| nombre de requêtes pouvant être servies simultanément à un moment donné | |
| ainsi que le nombre de processus autorisés (<directive | |
| module="mpm_common">MaxRequestWorkers</directive> / <directive | |
| module="mpm_common">ThreadsPerChild</directive>), alors que le | |
| scoreboard représente l'ensemble des processus en cours d'exécution et | |
| l'état de leurs threads de travail. Si le scoreboard est plein | |
| (autrement dit si aucun des threads n'est dans un état inactif) et si le | |
| nombre de requêtes actives servies est inférieur à <directive | |
| module="mpm_common">MaxRequestWorkers</directive>, cela signifie que | |
| certains d'entre eux bloquent les nouvelles requêtes qui pourraient être | |
| servies et sont en l'occurrence mises en attente (dans la limite de la | |
| valeur imposée par la directive <directive | |
| module="mpm_common">ListenBacklog</directive>). La plupart du temps, ces | |
| threads sont bloqués dans un état d'arrêt en douceur car ils attendent | |
| de terminer leur travail sur une connexion TCP pour s'arrêter et ainsi libérer | |
| une entrée dans le scoreboard (par exemple dans le cas du traitement des | |
| requêtes de longue durée, des clients lents ou des connexions en | |
| keep-alive). Voici deux scénarios courants :</p> | |
| <ul> | |
| <li>Pendant un <a href="../stopping.html#graceful">graceful | |
| restart</a>, le processus parent demande à tous ses processus | |
| enfants de terminer leur travail et de s'arrêter pendant qu'il | |
| recharge la configuration et lance de nouveaux processus. Si les | |
| processus existants continuent de s'exécuter pendant un certain | |
| temps avant de s'arrêter, le scoreboard sera partiellement occupé | |
| jusqu'à ce que les entrées correspondantes soient libérées. | |
| </li> | |
| <li>La charge du serveur diminue suffisamment pour que httpd | |
| commence à stopper certains processus (par exemple pour respecter la | |
| valeur de la directive <directive | |
| module="mpm_common">MaxSpareThreads</directive>). Cette situation | |
| est problèmatique car lorsque la charge augmente à nouveau, httpd va | |
| essayer de lancer de nouveaux processus. Si cette situation se | |
| répète, le nombre de processus peut augmenter sensiblement, | |
| aboutissant à un mélange d'anciens processus tentant de s'arrêter et | |
| de nouveaux processus tentant d'effectuer un travail quelconque. | |
| </li> | |
| </ul> | |
| <p>A partir de la version 2.4.24, mpm-event est plus intelligent et peut | |
| traiter les arrêts graceful de manière plus efficace. Voici certaines de | |
| ces améliorations :</p> | |
| <ul> | |
| <li>Utilisation de toutes les entrées du scoreboard dans la limite | |
| de la valeur définie par <directive | |
| module="mpm_common">ServerLimit</directive>. Les directives | |
| <directive module="mpm_common">MaxRequestWorkers</directive> et | |
| <directive module="mpm_common">ThreadsPerChild</directive> | |
| permettent de limiter le nombre de processus actifs, alors que la | |
| directive <directive module="mpm_common">ServerLimit</directive> | |
| prend aussi en compte les proccessus en arrêt graceful pour | |
| permettre l'utilisation d'entrées supplémentaires du scoreboard en | |
| cas de besoin. L'idée consiste à utiliser <directive | |
| module="mpm_common">ServerLimit</directive> pour indiquer à httpd | |
| conbien de processus supplémentaires seront tolérés avant | |
| d'atteindre les limites imposées par les ressources du système. | |
| </li> | |
| <li>Les processus en arrêt graceful doivent fermer leurs connexions | |
| en keep-alive.</li> | |
| <li>Lors d'un arrêt graceful, s'il y a plus de threads de travail en | |
| cours d'exécution que de connexions ouvertes pour un processus | |
| donné, ces threads sont arrêtés afin de libérer les ressources plus | |
| vite (ce qui peut s'avérer nécessaire pour lancer de nouveaux | |
| processus).</li> | |
| <li>Si le scoreboard est plein, empêche d'arrêter d'autres processus | |
| en mode graceful afin de réduire la charge jusqu'à ce que tous les | |
| anciens processus soient arrêtés (sinon la situation empirerait lors | |
| d'une remontée en charge).</li> | |
| </ul> | |
| <p>Le comportement décrit dans le dernier point est bien visible via | |
| <module>mod_status</module> dans la table des connexions avec les deux | |
| nouvelles colonnes "Slot" et "Stopping". La première indique le PID et | |
| la seconde si le processus est en cours d'arrêt ou non ; l'état | |
| supplémentaire "Yes (old gen)" indique un processus encore en exécution | |
| après un redémarrage graceful.</p> | |
| </section> | |
| <section id="limitations"><title>Limitations</title> | |
| <p>La gestion améliorée des connexions peut ne pas fonctionner pour | |
| certains filtres de connexion qui se sont déclarés eux-mêmes | |
| incompatibles avec le MPM Event. Dans ce cas, le MPM Event réadoptera le | |
| comportement du MPM <module>worker</module> et réservera un thread de | |
| travail par connexion. Notez que tous les modules inclus dans la | |
| distribution du serveur httpd sont compatibles avec le MPM Event.</p> | |
| <p>Une restriction similaire apparaît lorsqu'une requête utilise un | |
| filtre en sortie qui doit pouvoir lire et/ou modifier la totalité du | |
| corps de la réponse. Si la connexion avec le client se bloque pendant | |
| que le filtre traite les données, et si la quantité de données produites | |
| par le filtre est trop importante pour être stockée en mémoire, le | |
| thread utilisé pour la requête n'est pas libéré pendant que httpd attend | |
| que les données soient transmises au client.<br /> | |
| Pour illustrer ce cas de figure, nous pouvons envisager les deux | |
| situations suivantes : servir une ressource statique (comme un fichier | |
| CSS) ou servir un contenu issu d'un programme FCGI/CGI ou d'un serveur | |
| mandaté. La première situation est prévisible ; en effet, le MPM Event a | |
| une parfaite visibilité sur la fin du contenu, et il peut utiliser les | |
| évènements : le thread de travail qui sert la réponse peut envoyer les | |
| premiers octets jusqu'à ce que <code>EWOULDBLOCK</code> ou | |
| <code>EAGAIN</code> soit renvoyé, et déléguer le reste de la réponse au thread | |
| d'écoute. Ce dernier en retour attend un évènement sur le socket, et | |
| délègue le reste de la réponse au premier | |
| thread de travail disponible. Dans la deuxième situation par contre | |
| (FCGI/CGI/contenu mandaté), le MPM n'a pas de visibilité sur la fin de | |
| la réponse, et le thread de travail doit terminer sa tâche avant de | |
| rendre le contrôle au thread d'écoute. La seule solution consisterait | |
| alors à stocker la réponse en mémoire, mais ce ne serait pas l'option la | |
| plus sure en matière de stabilité du serveur et d'empreinte mémoire. | |
| </p> | |
| </section> | |
| <section id="background"><title>Matériel d'arrière-plan</title> | |
| <p>Le modèle event a été rendu possible par l'introduction de nouvelles | |
| APIs dans les systèmes d'exploitation supportés :</p> | |
| <ul> | |
| <li>epoll (Linux) </li> | |
| <li>kqueue (BSD) </li> | |
| <li>event ports (Solaris) </li> | |
| </ul> | |
| <p>Avant que ces APIs soient mises à disposition, les APIs | |
| traditionnelles <code>select</code> et <code>poll</code> devaient être | |
| utilisées. Ces APIs deviennent lentes si on les utilise pour gérer de | |
| nombreuses connexions ou si le jeu de connexions possède un taux de | |
| renouvellement élevé. Les nouvelles APIs permettent de gérer beaucoup | |
| plus de connexions et leur performances sont meilleures lorsque le jeu | |
| de connexions à gérer change fréquemment. Ces APIs ont donc rendu | |
| possible l'écriture le MPM Event qui est mieux adapté à la situation | |
| HTTP typique où de nombreuses connexions sont inactives.</p> | |
| <p>Le MPM Event suppose que l'implémentation de <code>apr_pollset</code> | |
| sous-jacente est raisonnablement sure avec l'utilisation des threads | |
| (threadsafe). Ceci évite au MPM de devoir effectuer trop verrouillages | |
| de haut niveau, ou d'avoir à réveiller le thread d'écoute pour lui | |
| envoyer un socket keep-alive. Ceci n'est possible qu'avec KQueue et | |
| EPoll.</p> | |
| </section> | |
| </section> | |
| <section id="requirements"><title>Prérequis</title> | |
| <p>Ce MPM dépend des opérations atomiques compare-and-swap | |
| d'<glossary>APR</glossary> pour la synchronisation des threads. Si | |
| vous compilez pour une plate-forme x86 et n'avez pas besoin du | |
| support 386, ou si vous compilez pour une plate-forme SPARC et | |
| n'avez pas besoin du support pre-UltraSPARC, ajoutez | |
| <code>--enable-nonportable-atomics=yes</code> aux arguments du | |
| script <program>configure</program>. Ceci permettra à APR | |
| d'implémenter les opérations atomiques en utilisant des instructions | |
| performantes indisponibles avec les processeurs plus | |
| anciens.</p> | |
| <p>Ce MPM ne fonctionne pas de manière optimale sur les | |
| plates-formes plus anciennes qui ne gèrent pas correctement les | |
| threads, mais ce problème est sans objet du fait du prérequis | |
| concernant EPoll ou KQueue.</p> | |
| <ul> | |
| <li>Pour utiliser ce MPM sous FreeBSD, la version 5.3 ou | |
| supérieure de ce système est recommandée. Il est cependant | |
| possible d'exécuter ce MPM sous FreeBSD 5.2.1 si vous utilisez | |
| <code>libkse</code> (voir <code>man libmap.conf</code>).</li> | |
| <li>Pour NetBSD, il est recommander d'utiliser la version 2.0 ou | |
| supérieure.</li> | |
| <li>Pour Linux, un noyau 2.6 est recommandé. Il faut aussi | |
| s'assurer que votre version de <code>glibc</code> a été compilée | |
| avec le support pour EPoll.</li> | |
| </ul> | |
| </section> | |
| <directivesynopsis location="mpm_common"><name>CoreDumpDirectory</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>EnableExceptionHook</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mod_unixd"><name>Group</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>Listen</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ListenBacklog</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>SendBufferSize</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>MaxRequestWorkers</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>MaxMemFree</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>MaxConnectionsPerChild</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>MaxSpareThreads</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>MinSpareThreads</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>PidFile</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ScoreBoardFile</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ServerLimit</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>StartServers</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ThreadLimit</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ThreadsPerChild</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mpm_common"><name>ThreadStackSize</name> | |
| </directivesynopsis> | |
| <directivesynopsis location="mod_unixd"><name>User</name> | |
| </directivesynopsis> | |
| <directivesynopsis> | |
| <name>AsyncRequestWorkerFactor</name> | |
| <description>Limite le nombre de connexions simultanées par thread</description> | |
| <syntax>AsyncRequestWorkerFactor <var>facteur</var></syntax> | |
| <default>2</default> | |
| <contextlist><context>server config</context> </contextlist> | |
| <compatibility>Disponible depuis la version 2.3.13</compatibility> | |
| <usage> | |
| <p>Le MPM event gère certaines connexions de manière asynchrone ; | |
| dans ce cas, les threads traitant la requête sont alloués selon les | |
| besoins et pour de courtes périodes. Dans les autres cas, un | |
| thread est réservé par | |
| connexion. Ceci peut conduire à des situations où tous les threads | |
| sont saturés et où aucun thread n'est capable d'effectuer de | |
| nouvelles tâches pour les connexions asynchrones établies.</p> | |
| <p>Pour minimiser les effets de ce problème, le MPM event utilise | |
| deux méthodes :</p> | |
| <ul> | |
| <li>il limite le nombre de connexions | |
| simultanées par thread en fonction du nombre de processus | |
| inactifs;</li> | |
| <li>si tous les processus sont occupés, il ferme des connexions | |
| permanentes, même si la limite de durée de la connexion n'a | |
| pas été atteinte. Ceci autorise les clients | |
| concernés à se reconnecter à un autre processus | |
| possèdant encore des threads disponibles.</li> | |
| </ul> | |
| <p>Cette directive permet de personnaliser finement la limite du | |
| nombre de connexions par thread. Un <strong>processus</strong> n'acceptera de | |
| nouvelles connexions que si le nombre actuel de connexions (sans | |
| compter les connexions à l'état "closing") est | |
| inférieur à :</p> | |
| <p class="indent"><strong> | |
| <directive module="mpm_common">ThreadsPerChild</directive> + | |
| (<directive>AsyncRequestWorkerFactor</directive> * | |
| <var>nombre de threads inactifs</var>) | |
| </strong></p> | |
| <p>Il est possible d'effectuer une estimation du nombre maximum de | |
| connexions simultanées pour tous les processus et pour un nombre donné moyen | |
| de threads de travail inactifs comme suit : | |
| </p> | |
| <p class="indent"><strong> | |
| (<directive module="mpm_common">ThreadsPerChild</directive> + | |
| (<directive>AsyncRequestWorkerFactor</directive> * | |
| <var>number of idle workers</var>)) * | |
| <directive module="mpm_common">ServerLimit</directive> | |
| </strong></p> | |
| <note><title>Exemple</title> | |
| <highlight language="config"> | |
| ThreadsPerChild = 10 | |
| ServerLimit = 4 | |
| AsyncRequestWorkerFactor = 2 | |
| MaxRequestWorkers = 40 | |
| idle_workers = 4 (moyenne pour tous les processus pour faire simple) | |
| max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit | |
| = (10 + (2 * 4)) * 4 = 72 | |
| </highlight> | |
| </note> | |
| <p>Lorsque tous les threads de travail sont inactifs, le nombre maximum | |
| absolu de connexions simultanées peut être calculé de manière plus simple :</p> | |
| <p class="indent"><strong> | |
| (<directive>AsyncRequestWorkerFactor</directive> + 1) * | |
| <directive module="mpm_common">MaxRequestWorkers</directive> | |
| </strong></p> | |
| <note><title>Exemple</title> | |
| <highlight language="config"> | |
| ThreadsPerChild = 10 | |
| ServerLimit = 4 | |
| MaxRequestWorkers = 40 | |
| AsyncRequestWorkerFactor = 2 | |
| </highlight> | |
| <p>Si tous les threads de tous les processus sont inactifs, alors :</p> | |
| <highlight language="config">idle_workers = 10</highlight> | |
| <p>Nous pouvons calculer le nombre maximum absolu de connexions simultanées | |
| de deux manières :</p> | |
| <highlight language="config"> | |
| max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit | |
| = (10 + (2 * 10)) * 4 = 120 | |
| max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers | |
| = (2 + 1) * 40 = 120 | |
| </highlight> | |
| </note> | |
| <p>Le réglage de la directive | |
| <directive>AsyncRequestWorkerFactor</directive> nécessite de connaître le | |
| trafic géré par httpd pour chaque style d'utilisation spécifique ; si vous | |
| modifiez la valeur par défaut, vous devrez par conséquent effectuer des | |
| tests approfondis en vous appuyant étroitement sur les données fournies par | |
| <module>mod_status</module>.</p> | |
| <p>La directive <directive | |
| module="mpm_common">MaxRequestWorkers</directive> se nommait | |
| <directive>MaxClients</directive> avant la version 2.3.13. La valeur | |
| ci-dessus montre que cet ancien nom ne correspondait pas à sa | |
| signification exacte pour le MPM event.</p> | |
| <p>La directive <directive>AsyncRequestWorkerFactor</directive> | |
| accepte des valeurs d'argument de type non entier, comme "1.5".</p> | |
| </usage> | |
| </directivesynopsis> | |
| </modulesynopsis> |