web-dev-qa-db-fra.com

tornade vs wsgi (avec gunicorn)

J'ai lu this à propos de Tornado:

D'un autre côté, si vous avez déjà une application WSGI et que vous souhaitez l'exécuter sur un tornado.httpserver.HTTPServer ultra rapide, encapsulez-la avec tornado.wsgi.WSGIContainer. Mais vous devez être prudent. Étant donné que votre application d'origine n'est pas préparée pour un serveur asynchrone et fera beaucoup d'E/S, elle bloquera les autres demandes tout en générant une réponse (les autres demandes seront acceptées et mises en mémoire tampon mais mises en file d'attente pour une manipulation ultérieure).

Et Guincorn dit:

'a Python WSGI HTTP Server for UNIX. Il s'agit d'un modèle de travail pré-fork porté à partir du projet Ruby’s Unicorn.

  1. Donc, Gunicorn va générer un processus de travail pour gérer la demande?
  2. Une demande concurrente par travailleur?
  3. Alors que la tornade utilisera epoll ou kqueue pour effectuer le travail en un seul processus (pas de processus maître/travailleur)?
  4. Donc, si j'utilise un appel de blocage (comme requests.get dans la fonction get/post du gestionnaire), Cela bloquera-t-il toute la gestion des demandes ou uniquement la demande en cours?
26
schemacs

Si vous exécutez une application WSGI sur Tornado, il n'y a pas beaucoup de différence entre Tornado et gunicorn dans la mesure où rien d'autre ne peut se produire tant que la demande WSGI est gérée par l'application dans un processus spécifique . Dans le cas de gunicorn car il n'a qu'une seule requête de gestion des threads et dans le cas de Tornado parce que la boucle d'événement principale ne pourra jamais s'exécuter pendant ce temps pour gérer les requêtes simultanées.

Dans le cas de Tornado, il existe également un danger caché.

Pour gunicorn, car il n'y a qu'un seul thread de demande, le processus de travail n'acceptera qu'une seule demande Web à la fois. S'il y a des demandes simultanées atteignant le serveur, elles seront traitées par tous les autres processus de travail disponibles à la place car ils partagent tous le même socket d'écoute.

Avec Tornado cependant, la nature asynchrone de la couche sous l'application WSGI signifie que plusieurs demandes peuvent être acceptées en même temps par un processus. Ils s'entrelaceront initialement au fur et à mesure de la lecture des en-têtes de demande et du contenu, que Tornado pré-lit en mémoire avant d'appeler l'application WSGI. Lorsque tout le contenu de la demande a ensuite été lu, le contrôle sera transféré à l'application WSGI pour gérer cette seule demande. Dans l'intervalle, la demande simultanée traitée par le même processus pour lequel les en-têtes de demande et le contenu n'avaient pas encore été lus sera bloquée aussi longtemps que l'application WSGI prendra pour gérer la première demande.

Maintenant, si vous n'avez qu'un seul processus Tornado, ce n'est pas grave car les demandes seraient de toute façon sérialisées, mais si vous utilisez le mode de travail tornado de gunicorn afin d'activer plusieurs processus de travail Tornado partageant les mêmes sockets d'écoute, cela peut être assez mauvais. En effet, la nature gourmande des processus individuels résultant de la couche asynchrone signifie que les demandes peuvent être bloquées dans un processus alors qu'un autre processus de travail aurait pu le gérer.

En résumé, pour un seul processus de serveur Web Tornado, vous ne pouvez gérer qu'une seule demande à la fois. Dans gunicorn, vous pouvez avoir plusieurs processus de travail pour permettre le traitement simultané des demandes. Utilisez une configuration multi-processus avec Tornado et vous risquez de voir les demandes bloquées.

Tornado peut donc être assez bon pour de très petites applications WSGI personnalisées où elles ne font pas grand-chose et la réponse est donc très rapide, mais elle peut souffrir lorsque vous avez de longues demandes en cours d'exécution sous une application WSGI bloquante. Gunicorn sera donc meilleur car il a la capacité appropriée de gérer les demandes simultanées. Le gunicorn étant cependant un thread unique et nécessitant plusieurs processus de travail, il utilisera beaucoup plus de mémoire.

Ils ont donc tous les deux des compromis et dans certains cas, vous pouvez être mieux en utilisant un serveur WSGI qui offre la simultanéité via le multithreading ainsi que plusieurs processus de travail. Cela vous permet de gérer les demandes simultanées, mais pas de gaspiller l'utilisation de la mémoire en nécessitant de nombreux processus de travail. Dans le même temps, vous devez équilibrer le nombre de threads par processus avec l'utilisation de plusieurs processus afin de ne pas souffrir indûment des effets du GIL dans une application gourmande en CPU.

Les choix pour les serveurs WSGI avec des capacités de multithreading sont mod_wsgi, uWSGI et serveuse. Pour la serveuse, vous êtes limité à un seul processus de travail.

En tout, quel est le meilleur serveur WSGI dépend vraiment beaucoup des spécificités de votre application web. Il n'y a pas de serveur WSGI unique qui soit le meilleur en tout.

41
Graham Dumpleton