¿Por qué necesito Nginx y algo como Gunicorn?

219

Estoy buscando una respuesta demasiado simplificada a la siguiente pregunta. Estoy tratando de construir una comprensión fundamental de cómo funciona Nginx junto con algo como Gunicorn.

¿Necesito Nginx y algo como Gunicorn para implementar aplicaciones de Django en Nginx?

Si es así, ¿qué maneja realmente las solicitudes HTTP?

PD. ¡No quiero usar Apache y mod_wsgi!

a.m
fuente
Apache y mod_wsgi es la forma más sencilla de implementar el puente entre su aplicación django y las solicitudes http que también es muy capaz en un entorno de producción. Para muchos desarrolladores, esto significa 'Apache es mejor que nginx' si lo supieran, pero como 'betamax es mejor que VHS', por desgracia, las reglas de Dogma
MagicLAMP

Respuestas:

314

Simplificado en exceso: necesita algo que ejecute Python, pero Python no es el mejor para manejar todo tipo de solicitudes.

[descargo de responsabilidad: soy un desarrollador de Gunicorn]

Menos simplificado: Independientemente del servidor de aplicaciones que utilice (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy), cualquier tipo de implementación no trivial tendrá algo en sentido ascendente que manejará las solicitudes que su aplicación Django no debería manejar. Ejemplos triviales de tales solicitudes están sirviendo activos estáticos (images / css / js).

Esto da como resultado dos primeros niveles de la clásica "arquitectura de tres niveles". Es decir, el servidor web (Nginx en su caso) manejará muchas solicitudes de imágenes y recursos estáticos. Las solicitudes que deben generarse dinámicamente se pasarán al servidor de aplicaciones (Gunicorn en su ejemplo). (Como comentario aparte, el tercero de los tres niveles es la base de datos)

Históricamente hablando, cada uno de estos niveles se alojaría en máquinas separadas (y probablemente habría varias máquinas en los primeros dos niveles, es decir: 5 servidores web envían solicitudes a dos servidores de aplicaciones que a su vez consultan una sola base de datos).

En la era moderna ahora tenemos aplicaciones de todas las formas y tamaños. No todos los proyectos de fin de semana o sitios de pequeñas empresas realmente necesitan la potencia de varias máquinas y funcionarán muy bien en una sola caja. Esto ha generado nuevas entradas en la gama de soluciones de alojamiento. Algunas soluciones unirán el servidor de aplicaciones con el servidor web (Apache httpd + mod_wsgi, Nginx + mod_uwsgi, etc.). Y no es nada raro alojar la base de datos en la misma máquina que una de estas combinaciones de servidor web / aplicación.

Ahora, en el caso de Gunicorn, tomamos una decisión específica (copiando de Ruby's Unicorn) para mantener las cosas separadas de Nginx mientras confiamos en el comportamiento de representación de Nginx. Específicamente, si podemos suponer que Gunicorn nunca leerá conexiones directamente desde Internet, entonces no tenemos que preocuparnos por los clientes que son lentos. Esto significa que el modelo de procesamiento para Gunicorn es vergonzosamente simple.

La separación también permite que Gunicorn se escriba en Python puro, lo que minimiza el costo de desarrollo sin afectar significativamente el rendimiento. También permite a los usuarios la capacidad de usar otros servidores proxy (suponiendo que se almacenan correctamente).

En cuanto a su segunda pregunta sobre qué maneja realmente la solicitud HTTP, la respuesta simple es Gunicorn. La respuesta completa es que tanto Nginx como Gunicorn manejan la solicitud. Básicamente, Nginx recibirá la solicitud y, si se trata de una solicitud dinámica (generalmente basada en patrones de URL), le dará esa solicitud a Gunicorn, que la procesará, y luego devolverá una respuesta a Nginx que luego reenviará la respuesta al original cliente.

Así que para terminar, sí. Necesita tanto Nginx como Gunicorn (o algo similar) para una implementación adecuada de Django. Si está buscando específicamente alojar Django con Nginx, entonces investigaría a Gunicorn, mod_uwsgi y tal vez CherryPy como candidatos para el lado de Django.

Paul J. Davis
fuente
14
¡Gracias por tomarse el tiempo para escribir una respuesta tan detallada! ¿Alguna lectura recomendada sobre esta "arquitectura de 3 niveles"?
Soy el
55
Gran respuesta, sin embargo, no entiendo el problema con los clientes lentos.
Mads Skjern
3
@MadsSkjern Supongo que aquí, pero si asumes que todos los clientes son rápidos, puedes usar un grupo fijo de procesos de trabajo y no tienes que codificar el caso en el que muchos o todos se bloquean esperando a un cliente.
Jonathan Hartley
77
mi aplicación django solo sirve json sin contenido estático, ¿puedo ir con gunicorn y sin nginx
Sar009
27

Me gustó esta explicación en su simplicidad:

Nginx se enfrentará al mundo exterior. Servirá archivos multimedia (imágenes, CSS, etc.) directamente desde el sistema de archivos. Sin embargo, no puede hablar directamente con las aplicaciones de Django; necesita algo que ejecute la aplicación, alimente las solicitudes de la web y devuelva respuestas.

Ese es el trabajo de Gunicorn. Gunicorn creará un socket Unix y responderá a nginx a través del protocolo wsgi: el socket pasa datos en ambas direcciones:

The outside world <-> Nginx <-> The socket <-> Gunicorn

https://gist.github.com/Atem18/4696071

Juuso Ohtonen
fuente
No tiene que ser enchufes, en caso de que otros se lo pregunten.
akshay
0

Estoy buscando una respuesta demasiado simplificada ...

¿Necesito Nginx y algo como Gunicorn para implementar aplicaciones de Django en Nginx?

Si es así, ¿qué maneja realmente las solicitudes HTTP?

Respuesta demasiado simplificada:

SI.

Tanto Nginx como Gunicorn.

Como está implementando en Nginx, por supuesto que necesita Nginx.

Dado que está implementando Django, que es un marco web, necesita algo que reduzca la conversación entre el servidor web (Nginx) y el marco web (Django). En el mundo de Python, tal cosa se llama un servidor WSGI (pero piensa que es un software intermedio), cuyos ejemplos incluyen Gunicorn y uWSGI. Al manejar una solicitud, Nginx envía la solicitud a Gunicorn o uWSGI, que a su vez llama al código de Django y devuelve la respuesta.

Este documento y la respuesta de Paul lo ayudarán a aprenderlo mejor.

Cyker
fuente
0

Gunicorn es un desperdicio de recursos. Simplemente puede pasar proxy a django escuchando en un puerto en lugar de ejecutar gunicorn en la parte superior de django y nuevamente nginx en la parte superior de todo eso. En los puntos de referencia, he visto un aumento de velocidad muy notable. Nginx puede manejar fácilmente solicitudes directas a django. Gunicorn no es más que un paso elevado (en realidad un paso elevado más lento) sobre el camino normal. Simplemente se sienta y come sus recursos e intenta afirmar que está impulsando su sitio web.

nginx básicamente almacena todas las solicitudes y maneja las solicitudes de archivos estáticos por sí mismo (si lo ha configurado así). Y envía todo el contenido dinámico a otro servidor (gunicorn / django).

Gunicorn no tiene otro uso que simplemente pasar la solicitud a la aplicación. Es como una pajita que puedes beber directamente del vaso o beber de la pajita a un ritmo limitado (aquí la persona que bebe es django). Y nginx es el camarero que te trajo el vaso de jugo.

He comparado y encontrado esto - con gunicorn: 22k req / s sin gunicorn: 34k req / s

Su sitio necesitará los requisitos adicionales en carga pesada.

ShadowDoom
fuente
1
¿Estás hablando de ejecutar el servidor de desarrollo en producción?
Michael Hampton
El servidor de desarrollo se puede ejecutar detrás de un servidor de producción (como nginx). Porque recibirá las solicitudes en el lugar correcto y el servidor de producción se encargará de la seguridad y la eficiencia. Es como usar solo el matraz WSGI +. En su lugar, puede usar solo nginx + django (sin ningún tipo de acumulación de middleware, como gunicorn). Pruebe la configuración con carga pesada y lo comprenderá.
ShadowDoom
1
github.com/django/channels/issues/142 (TLDR: es una mala idea)
igor