Serveur HTTP Apache Version 2.5

| Description: | Un MPM (Multi-Processing Module) événementiel léger, rapide et autonome basé sur l'ensemble de requêtes et le pool de threads APR, particulièrement adapté comme mandataire inverse |
|---|---|
| Statut: | MPM |
| Identificateur de Module: | mpm_motorz_module |
| Fichier Source: | motorz.c |
Le MPM motorz est une implémentation évènementielle
asynchrone. Il combine un ensemble fixe de processus enfants de style prefork
avec un cœur construit sur l’ensemble de requêtes d’APR
et un jeu de threads partagés. Chaque processus enfant exécute un ou
plusieurs threads sondeurs dédiés qui surveillent les sockets et
les compteurs de délai tout en répartissant les évènements d’entrée/sortie prêts
et les compteurs de délai expirés parmi un jeu de threads de travail. Les
threads de travail ne sondent jamais ; ils ne font que traiter les
connexions/requêtes qui leur sont envoyées.
Le but est de concevoir un MPM rapide, efficace, autonome et compact qui fonctionne sur les plateformes Unix modernes en s’appuyant le plus possible sur APR, tout en prenant en charge la gestion des connexions asynchrones nécessaire à l’efficacité des connexions persistantes et de HTTP/2.
Pour utiliser le MPM motorz, ajoutez
--with-mpm=motorz aux arguments du script
configure lors de la construction de
httpd, ou construisez le en tant que module chargeable
avec --enable-mpms-shared=motorz.
Comment cela fonctionne-t-il
Gestion des connexions asynchrones
Contrôle d’admission
Liens de parenté avec les autres MPMs
CoreDumpDirectory
EnableExceptionHook
Group
Listen
ListenBacklog
MaxConnectionsPerChild
MaxMemFree
PidFile
PollersPerChild
ScoreBoardFile
SendBufferSize
StartServers
ThreadLimit
ThreadsPerChild
ThreadStackSize
Usermotorz utilise prefork comme cadre pour la gestion des
processus et un cœur à base d’évènements pour la gestion des connexions. Un
seul processus de contrôle (le parent) lance un nombre fixe de processus
enfants, ce nombre étant défini par la directive StartServers. À la différence des MPM
worker et event, le nombre de processus
enfants ne varie pas avec la charge : motorz maintient un
jeu de processus statique en les remplaçant nombre pour nombre lorsqu’ils
quittent. Le parallélisme de traitement au sein d’un hôte est mis en œuvre
en ajoutant des threads de travail (ThreadsPerChild) et, lorsque le cheminement
du processus de sondage/répartition constitue un goulot d’étranglement, des
threads sondeurs (PollersPerChild), au lieu de lancer
davantage de processus.
Chaque processus enfant exécute :
PollersPerChild.ThreadsPerChild) qui gère la connexion
proprement dite et traite les requêtes qui lui sont envoyées. Les
threads de travail ne sondent jamais.MaxConnectionsPerChild et la
"pipe-of-death / generation", enjoint les threads sondeurs de ralentir
et les rejoint lorsqu’ils quittent.Une connexion est attribuée à un thread sondeur au moment de
l'acceptation (round-robin) et le reste pendant toute sa durée de vie : elle
réinitialise et fait passer à l’état expiré le domaine de sondage et la
sonnerie du chronomètre de ce thread sondeur. Utiliser plusieurs threads
sondeurs augmente le plafond de débit par rapport à celui d’un sondage par
thread unique ; ainsi l’acceptation, la répartition des évènements et
l’expiration du délai sont réglées par
PollersPerChild au lieu d’être sérialisées sur un
seul thread.
Alors que le processus parent est en général démarré en tant que
root sous Unix de façon à se lier au port 80, les processus
enfants et les threads sont lancés par le serveur sous un utilisateur moins
privilégié. Les directives User et
Group permettent de définir les
privilèges des processus enfants du serveur HTTP Apache. Les processus enfants
doivent pouvoir lire tout le contenu destiné à être servi, mais cela mis à
part, doivent posséder le moins de privilèges possible.
La directive MaxConnectionsPerChild permet de contrôler
la fréquence à laquelle le serveur recycle les processus en retirant les
anciens et en en lançant de nouveaux.
motorz se définit lui-même comme un MPM asynchrone.
Lorsqu’un thread de travail termine la phase active d’une connexion (par
exemple, une connexion persistante HTTP entre les requêtes ou une connexion
attendant une entrée/sortie), il confie le socket à son thread sondeur au
lieu de maintenir un thread de travail inactif. Le thread sondeur attend le
prochain évènement sur ce socket (dans les limites du délai défini par la
directive Timeout) et n’attribue
la connexion à un thread de travail que s’il y a quelque chose à faire. Cela
libère les threads de travail des connexions persistantes inactives et
permet une gestion efficace de HTTP/2 où la connexion principale est reprise
par le MPM entre les requêtes.
La fermeture avec délai (lingering close) n’est, elle non plus, pas bloquante : plutôt que de bloquer un thread de travail pendant la durée du délai de fermeture, le socket en cours de vidage est confié à la boucle de sondage avec un délai d’inaction limité ; ainsi, le thread de travail est replacé dans le pool immédiatement.
Les modules qui acceptent une connexion totalement asynchrone (la suspendant et la réactivant plus tard) sont pris en charge ; une connexion suspendue est parquée et réarmée sur son propre thread sondeur lorsqu’elle est réactivée.
Pour qu’un processus enfant reste fiable en cas de surcharge,
motorz applique une pression en retour (backpressure) à
l’écouteur. Lorsque le pool de threads de travail sature, le thread sondeur
qui possède les sockets d’écoute les enlève de son domaine de sondage et
arrête d’accepter ; il les réajoute lorsque la liste de demandes se
vide. Cela a pour effet de limiter la taille de la file d’attente de
travaux et la mémoire consommée par connexion, au lieu de les laisser
grandir sans limite. La décision se base sur le décompte des threads
inactifs, en attente et actifs dans le pool de threads de travail, avec
hystérèse pour éviter un basculement excessif des écouteurs entre « on » et
« off ».
Ètant donné que la marque des « basses eaux » du contrôle d’admission est
une fraction de la valeur de la directive ThreadsPerChild, une très petite valeur pour
cette dernière (en particulier ThreadsPerChild 1) fait que les
écouteurs ne sont réactivés que lorsque la file d’attente de travaux est
totalement vide, ce qui dégrade sévèrement le débit. Une valeur d’au moins 4
pour ThreadsPerChild est fortement recommandée ; si cette
valeur est inférieure à 4, le serveur émet un avertissement.
motorz utilise prefork pour la gestion des processus et
un pool de threads de travail APR, avec des threads sondeurs qui
répartissent le travail au sein du pool de threads de travail. Cette
approche est différente de la conception écouteur,thread de travail/fdqueue
du MPM event dans laquelle les threads de travail réarment
eux-mêmes un domaine de sondage partagé et sûr en ce qui concerne les
threads.
La charge de travail détermine si l’ajout de threads sondeurs peut aider.
Si les threads de travail constituent le goulot d’étranglement du
CPU#8212;c’est en général le cas pour le traitement réel des
requêtes#8212;les threads sondeurs ne sont pas le facteur de limitation et
une valeur de la directive PollersPerChild au delà
de 1 ou 2 sera de peu d’effet. La conception à plusieurs threads sondeurs
supprime le plafond structurel de la conception à thread sondeur
unique, mais le débit par hôte reste tout de même gouverné par le CPU de
travail.
À la différence des MPMs worker et
event, motorz ne modifie pas le nombre de
processus enfants avec la charge et ne définit pas de plafond séparé avec
ServerLimit. Le nombre de
processus enfants est fixé par la directive StartServers qui agit de ce fait comme une
limite physique du démon, et il n’y a pas de contrôles du style MinSpareThreads, MaxSpareThreads ou MaxRequestWorkers. Il est possible de
définir le parallélisme du traitement avec la directive ThreadsPerChild (et, si le processus de
sondage sature, avec la directive PollersPerChild).
| Description: | Nombre de threads sondeurs par processus enfant |
|---|---|
| Syntaxe: | PollersPerChild number |
| Défaut: | PollersPerChild 0 |
| Contexte: | configuration globale |
| Statut: | MPM |
| Module: | motorz |
La directive PollersPerChild permet de définir le
nombre de threads sondeurs pour chaque processus enfant. Chaque thread
sondeur possède ses propres domaine de sondage, sonnerie de chronomètre et
liste de recyclage de connexion, et gère une partie des connexions du
processus enfant ; ajouter des threads sondeurs augmente donc la fréquence à
laquelle un seul processus enfant peut accepter des connexions et répartir
les évènements d’entrée/sortie et les expirations de délai.
Une valeur de 0 (la valeur par défaut) signifie que le
nombre de threads sondeurs est calculé automatiquement : il est
déduit du nombre de CPUs en ligne, plafonné à un maximum codé en dur. Dans
tous les cas, le nombre de threads sondeurs est contraint de façon qu’il ne
dépasse jamais la valeur de la directive ThreadsPerChild et ne soit jamais inférieur
à un.
Étant donné que la répartition d’évènements est rarement le goulot
d’étranglement pour le traitement des requêtes réelles—il s’agit en
général du CPU de travail—des valeurs au-delà de un ou deux améliorent
rarement le débit. Augmenter PollersPerChild s’avère
principalement utile pour les charges de travail dominées par une rotation
très importante des connexions ou un grand nombre de connexions à base
d’évènements et inactives, où le processus de sondage/acceptation devient la
limite.
StartServers 2 ThreadsPerChild 64 ThreadLimit 64 PollersPerChild 2