nginx: son multithread mais utilise plusieurs processus?

J’essaie de comprendre ce qui rend Nginx si rapide et j’ai quelques questions à vous poser.

Si je comprends bien, Apache crée un nouveau processus pour traiter chaque demande OU crée un nouveau thread pour répondre à chaque requête. Étant donné que chaque nouveau thread partage un espace d’adresse virtuel, l’utilisation de la mémoire continue d’augmenter si plusieurs demandes concurrentes arrivent.

Nginx résout ce problème en ayant un seul processus d’écoute (Master), avec un seul thread d’exécution ET 2 ou 3 processus (nombre est configurable). Ce processus / thread maître exécute une boucle d’événement. Attendre efficacement toute demande entrante. Lorsqu’une demande arrive, elle la transmet à l’un des processus de travail.

Veuillez me corriger si ma compréhension ci-dessus n’est pas correcte

Si ce qui précède est correct, alors j’ai quelques questions:

1.) Le processus de travail ne va-t-il pas engendrer des threads multiples et rencontrer le même problème que Apache?

2.) Ou nginx fast parce que son architecture basée sur les événements utilise des IO non bloquantes sous tout. Peut-être que le processus de travail génère des threads qui ne font que des IO non bloquantes, n’est-ce pas?

3.) Qu’est-ce que “exactement” est une “architecture basée sur les événements”, est-ce que quelqu’un peut vraiment le simplifier, pour que je le comprenne bien. Est-ce que cela ne concerne que le non-blocage ou autre chose?

J’ai eu une référence à c10k , j’essaie de la parcourir, mais je ne pense pas que ce soit à propos de l’événement basé sur l’arc. il semble plus pour les IO non bloquantes.

Ce n’est pas très compliqué d’un sharepoint vue conceptuel. Je vais essayer d’être clair, mais je dois faire quelques simplifications.

Les serveurs basés sur des événements (comme nginx et lighttpd ) utilisent un wrapper autour d’un système de surveillance d’événements. Par exemple. lighttpd utilise libevent pour abstraire le système de surveillance des événements haute vitesse plus avancé (voir également libev ).

Le serveur garde la trace de toutes les connexions non bloquantes qu’il possède (à la fois en écriture et en lecture) en utilisant une machine d’état simple pour chaque connexion. Le système de surveillance d’événements notifie le processus du serveur lorsqu’il y a de nouvelles données disponibles ou lorsqu’il peut écrire plus de données. C’est comme un select() sur les stéroïdes, si vous connaissez la programmation socket. Le processus serveur envoie alors simplement le fichier demandé en utilisant une fonction avancée telle que sendfile() dans la mesure du possible ou transforme la requête en un processus CGI utilisant un socket pour la communication (cette socket sera surveillée avec le système de surveillance des événements comme les autres connexions réseau).

Ce lien contient de nombreuses informations sur les composants internes de nginx, au cas où. J’espère que ça aide.

Apache utilise plusieurs threads pour fournir à chaque requête son propre thread d’exécution. Ceci est nécessaire pour éviter le blocage lors de l’utilisation d’E / S synchrones.

Nginx utilise uniquement des E / S asynchrones, ce qui rend le blocage d’un non-problème. La seule raison pour laquelle nginx utilise plusieurs processus est d’utiliser pleinement les systèmes multi-core, multi-processeurs et hyper-threading. Même avec le support SMP, le kernel ne peut pas planifier un seul thread d’exécution sur plusieurs processeurs. Il nécessite au moins un processus ou thread par CPU logique.

La différence est que nginx ne nécessite que suffisamment de processus de travail pour tirer pleinement parti de SMP, alors que l’architecture d’Apache nécessite la création d’un nouveau thread (chacun avec sa propre stack d’environ ~ 8 Mo) par requête. De toute évidence, dans des conditions de concurrence élevée, Apache utilisera beaucoup plus de mémoire et subira une surcharge de maintenance liée au grand nombre de threads.

Apache ne génère pas de nouveau thread pour chaque requête. Il conserve un cache de threads ou un groupe de processus pré-forkés auxquels il envoie des requêtes. Le nombre de requêtes simultanées est limité par le nombre d’enfants / threads, mais apache ne génère pas de nouveau thread / enfant pour chaque requête qui serait ridiculement lente (même avec les threads, la création et le déassembly de chaque requête seraient beaucoup trop lents) )

Nginx utilise un modèle maître-ouvrier. Le processus principal traite du chargement de la configuration et de la création / destruction / maintenance des travailleurs. Comme apache, il commence par un certain nombre de processus pré-forkés qui sont déjà en cours d’exécution et dont l’un est le processus “master”. Chaque processus de travail partage un ensemble de sockets d’écoute. Chaque processus de travail accepte les connexions et les traite, mais chaque travailleur peut gérer des milliers de connexions à la fois, contrairement à Apache qui ne peut gérer qu’une connexion par travailleur.

La façon dont nginx y parvient passe par le “multiplexage”. Il n’utilise pas libevent, il utilise une boucle d’événement personnalisée qui a été conçue spécifiquement pour nginx et a évolué au cours du développement avec le développement du logiciel nginx. Le multiplexage fonctionne en utilisant une boucle pour “incrémenter” un fragment de programme par bloc fonctionnant sur un élément de données / une nouvelle connexion / quelle que soit la connexion / l’object par itération de boucle. Tout est basé sur des backends comme Epoll () kqueue () et select (). Que vous devriez lire sur