Epoll est-il la raison essentielle pour laquelle Tornadoweb (ou Nginx) est si rapide?
Tornadoweb et Nginx sont des serveurs Web populaires pour le moment et de nombreux benchmarkings montrent qu'ils ont de meilleures performances Qu'Apache dans certaines circonstances. Donc ma question est la suivante:
Est-ce que 'epoll' est la raison la plus essentielle qui les rend si rapides? Et que puis-je apprendre que si je veux écrire un bon serveur socket?
2 réponses
Si vous cherchez à écrire un serveur socket, un bon point de départ est L'article C10k de Dan Kegel datant de quelques années:
Http://www.kegel.com/c10k.html
J'ai également trouvé le Guide de Beej sur la programmation réseau très pratique:
Enfin, si vous avez besoin d'une bonne référence, il y a la programmation réseau UNIX par W. Richard Stevens et. Al.:
Http://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551/ref=dp_ob_title_bk
Quoi qu'il en soit, pour répondre à votre question, la principale différence entre Apache et Nginx est Qu'Apache utilise un thread par client avec des e/s bloquantes, alors que Nginx est mono-thread avec des e/s non bloquantes. client. Nginx, d'autre part, gère toutes les demandes dans un thread. Lorsqu'une requête doit faire une requête réseau (par exemple, à un backend), Nginx attache un rappel à la requête backend et travaille ensuite sur une autre requête client active. En pratique, cela signifie qu'il retourne à la boucle d'événement(epoll
, kqueue
, ou select
) et demande des descripteurs de fichiers qui ont quelque chose à signaler. Notez que l'appel système dans la boucle main event est en fait une opération de blocage, car il n'y a rien à faire jusqu'à ce qu'un des descripteurs de fichier est prêt pour la lecture ou l'écriture.
C'est donc la principale raison pour laquelle Nginx et Tornado sont efficaces pour servir de nombreux clients simultanés: il n'y a qu'un seul processus (économisant ainsi de la RAM) et un seul thread (économisant ainsi le CPU des commutateurs de contexte). Quant à epoll, c'est juste une version plus efficace de select. S'il y a N descripteurs de fichiers ouverts(sockets), il vous permet de choisir ceux prêts à lire dans O(1) au lieu de O (N) time. En fait, Nginx peut utiliser select à la place de epoll si vous le compilez avec l'option --with-select_module
, et je parie que ce sera toujours plus efficace Qu'Apache. Je ne suis pas aussi familier avec les internes D'Apache, mais un grep rapide montre qu'il utilise select et epoll-probablement lorsque le serveur écoute plusieurs ports / interfaces, ou s'il effectue des requêtes backend simultanées pour un seul client.
Incidemment, j'ai commencé avec ce genre de choses en essayant d'écrire un serveur de socket de base et je voulais comprendre comment Nginx était si efficace. Après en parcourant le code source Nginx et en lisant les guides / livres auxquels j'ai lié ci-dessus, j'ai découvert qu'il serait plus facile d'écrire des modules Nginx au lieu de mon propre serveur. C'est ainsi que naquit le désormais semi-légendaire Guide D'Emiller pour le développement de modules Nginx:
Http://www.evanmiller.org/nginx-modules-guide.html
(attention: le Guide a été écrit contre Nginx 0.5-0.6 et les API peuvent avoir changé.) Si vous faites quelque chose avec HTTP, je dirais de donner un coup de feu à Nginx car cela a fonctionné tous les détails poilus de traiter avec des clients stupides. Par exemple, le petit serveur socket que j'ai écrit pour le plaisir a très bien fonctionné avec tous les clients-sauf Safari, et je n'ai jamais compris pourquoi. Même pour d'autres protocoles, Nginx pourrait être la bonne voie à suivre; le concours complet est assez bien abstrait des protocoles, c'est pourquoi il peut proxy HTTP ainsi que IMAP. La base de code Nginx est extrêmement bien organisée et très bien écrite, à une exception près. Je ne suivrais pas son exemple quand il s'agit de lancer à la main un analyseur de protocole; à la place, utilisez un générateur d'analyseur. J'ai écrit quelques trucs sur l'utilisation d'un générateur d'analyseur (Ragel) avec Nginx ici:
Http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing
Tout cela était probablement plus d'informations que vous ne le vouliez, mais j'espère que vous en trouverez une partie utile.
Oui et non. Bien qu'ils utilisent tous deux epoll, techniquement, ils utilisent tous deux une boucle d'événement pour gérer les demandes. Vous pouvez trouver plus d'informations sur ce que sont les boucles d'événements et comment elles sont utilisées sur wikipedia.
Découvrez libevent (utilisé par gevent, généralement plus rapide et plus stable que la tornade) ou libev pour les implémentations.