Cette réponse est complémentaire des autres et explique pourquoi Unicorn a besoin de nginx devant elle .
TL; DR La raison pour laquelle Unicorn est généralement déployé avec un proxy inverse comme nginx est que ses créateurs l'ont délibérément conçu ainsi, faisant un compromis pour la simplicité.
Tout d'abord, rien ne vous empêche de déployer Unicorn sans proxy inverse. Cependant, ce ne serait pas une très bonne idée; voyons pourquoi.
Unicorn suit la philosophie Unix qui est de faire une chose et de bien la faire , à savoir servir des clients rapides et à faible latence (nous verrons ce que cela signifie plus tard). Le fait que Unicorn soit conçu pour les clients rapides et à faible latence implique également que ce n'est pas très bon avec les clients lents et à latence élevée , ce qui est en effet vrai. C'est l'un des points faibles de Unicorn et c'est là qu'un proxy inverse entre en jeu: il se trouve devant Unicorn et s'occupe de ces clients lents (nous verrons comment plus tard).
Heureusement, un tel proxy inverse existe déjà et s'appelle nginx .
La décision de ne gérer que les clients rapides, simplifie grandement la conception de Unicorn et permet une base de code beaucoup plus simple et plus petite, au prix d'une complexité supplémentaire sur le département de déploiement (c'est-à-dire que vous devez également déployer nginx en plus de Unicorn).
Une autre décision pourrait être de concevoir Unicorn de manière à ne pas avoir besoin d'un proxy inverse. Cependant, cela signifie qu'il devrait implémenter des fonctionnalités supplémentaires pour faire tout ce que fait maintenant nginx, ce qui entraîne une base de code plus complexe et plus d'efforts d'ingénierie.
Au lieu de cela, ses créateurs ont pris la décision de tirer parti des logiciels existants qui sont testés au combat et très bien conçus et d'éviter de perdre du temps et de l'énergie sur des problèmes déjà résolus par d'autres logiciels.
Mais soyons techniques et répondons à votre question:
Pourquoi Unicorn doit-il être déployé avec nginx?
Voici quelques-unes des principales raisons:
Unicorn utilise des E / S bloquantes pour les clients
S'appuyer sur un proxy inverse signifie que Unicorn n'a pas besoin d'utiliser des E / S non bloquantes. Au lieu de cela, il peut utiliser des E / S de blocage, ce qui est par nature plus simple et plus facile à suivre pour le programmeur.
Également comme l' indique le document DESIGN :
[Utiliser des E / S bloquantes] permet de suivre un chemin de code plus simple dans l'interpréteur Ruby et moins d'appels système.
Cependant, cela a également des conséquences:
Point clé n ° 1: Unicorn n'est pas efficace avec les clients lents
(Par souci de simplicité, nous supposons une configuration avec 1 ouvrier Licorne)
Étant donné que le blocage des E / S est utilisé, un worker Unicorn ne peut servir qu'un client à la fois , donc un client lent (c'est-à-dire un avec une connexion lente) garderait effectivement le travailleur occupé plus longtemps (qu'un client rapide le ferait) ). En attendant, les autres clients attendraient simplement que le travailleur soit à nouveau libre (c'est-à-dire que les demandes s'accumulaient dans la file d'attente).
Pour contourner ce problème, un proxy inverse est déployé devant Unicorn, qui met complètement en mémoire tampon les demandes entrantes et les réponses de l'application, puis envoie chacune d'elles à la fois (c'est-à-dire les nourrit à la cuillère) à Unicorn et aux clients, respectivement. À cet égard, on pourrait dire que le proxy inverse «protège» Unicorn des clients réseau lents.
Heureusement, Nginx est un excellent candidat pour ce rôle, car il est conçu pour gérer efficacement des milliers de centaines de clients simultanés.
Il est d'une importance cruciale que le proxy inverse se trouve dans le même réseau local que Unicorn (généralement dans la même machine physique communiquant avec Unicorn via un socket de domaine Unix), afin que la latence du réseau soit réduite au minimum.
Ainsi, un tel proxy joue efficacement le rôle d'un client rapide qu'Unicorn est conçu pour servir en premier lieu, car il transmet rapidement les demandes à Unicorn et maintient les travailleurs occupés pendant le laps de temps le plus court possible (par rapport au temps passé par un client. avec une connexion lente ferait).
Point clé n ° 2: Unicorn ne prend pas en charge HTTP / 1.1 keep-alive
Étant donné que Unicorn utilise des E / S bloquantes, cela signifie également qu'il ne peut pas prendre en charge la fonction de maintien en vie HTTP / 1.1, car les connexions persistantes des clients lents occuperaient rapidement tous les travailleurs Unicorn disponibles.
Par conséquent, pour tirer parti de HTTP keep-alive, devinez quoi: un proxy inverse est utilisé.
nginx, d'autre part, peut gérer des milliers de connexions simultanées en utilisant seulement quelques threads. Par conséquent, il n'a pas les limites de concurrence qu'un serveur comme Unicorn a (qui se limite essentiellement à la quantité de processus de travail), ce qui signifie qu'il peut très bien gérer les connexions persistantes. Vous trouverez plus d'informations sur la façon dont cela fonctionne réellement ici .
C'est pourquoi nginx accepte les connexions persistantes des clients et les met en proxy à Unicorn via des connexions simples via généralement un socket Unix.
Point n ° 3: Unicorn n'est pas très bon pour servir des fichiers statiques
Encore une fois, servir des fichiers statiques est une chose que Unicorn peut faire mais n'est pas conçue pour le faire efficacement.
D'un autre côté, les proxys inverses comme nginx sont bien plus performants (c'est-à-dire sendfile(2)
et la mise en cache).
Plus
Il y a d'autres points qui sont décrits dans le document PHILOSOPHY (voir «Amélioration des performances grâce au proxy inverse» ).
Voir également certaines des fonctionnalités de base de nginx .
Nous voyons qu'en tirant parti des logiciels existants (c.-à-d. Nginx) et en suivant la philosophie Unix de «faire une chose et bien le faire», Unicorn est capable de suivre une conception et une implémentation plus simples tout en restant efficace pour servir les applications Rack (par exemple. votre application Rails).
Pour plus d'informations, reportez-vous à la philosophie et aux documents de conception de Unicorn qui expliquent plus en détail les choix derrière la conception de Unicorn et pourquoi nginx est considéré comme un bon proxy inverse pour Unicorn.