
Hace no mucho que empecé a escuchar sobre Gunicorn, creo que allá por Marzo cuando Lorenzo Gil se encontraba en la PyCon 2011, pero no me había propuesto probarlo hasta hace unos días. Pero bueno, empecemos por el principio…
¿Qué es Gunicorn?
Gunicorn, también conocido como Green Unicorn (Unicornio Verde), es un servidor WSGI HTTP para Python. Es un pre-fork del proyecto Unicorn de Ruby.
Gunicorn es compatible con varios web frameworks, soporta WSGI, Django y Paster de forma nativa; consume pocos recursos en ejecución y es bastante rápido.
Como he comentado en el párrafo anterior, soporta nativamente WSGI, Django y Paster; administra los workers de forma automática, permite establecer hooks para hacerlo más extensible, compatible con Python 2.5 o superior.
Instalando Gunicorn
Su instalación es realmente sencilla, justo como cualquier otro módulo de Python.
$ pip install gunicorn
o si lo preferimos, podemos obtener el código con git e instalarlo como cualquier otra aplicación en Python.
$ git clone git://github.com/benoitc/gunicorn.git $ cd gunicorn $ python setup.py install
Una vez instalado Gunicorn tendremos a nuestra disposición tres comandos con los que servir diferentes web frameworks.
Ejecutando Gunicorn
Los comandos disponibles en Gunicorn son:
- gunicorn: utilizado para servir aplicaciones WSGI.
- gunicorn_django: utilizado para servir aplicaciones Django.
- gunicorn_paster: para frameworks compatibles con Paster como Pylons, TurboGears 2, …
En este post me centraré en el comando gunicorn pero podeis encontrar más información de cada uno de ellos en la documentación oficial de Gunicorn.
Configurando Gunicorn
La configuración de Gunicorn también es muy sencilla, básicamente consiste en un fichero Python que tenga permisos de lectura en el sistema de ficheros, excepto que nuestra aplicación haya sido desarrollada utilizando Paster, en este caso haremos uso de un fichero INI.
Su sintaxis de uso es:
$ gunicorn [OPTIONS] APP_MODULE
Donde APP_MODULE está compuesto por $(MODULE_NAME):$(VARIABLE_NAME). Un ejemplo de uso sería el siguiente:
$ gunicorn --workers 2 prueba:aplicacion
Gunicorn buscará el módulo, es decir, el fichero prueba.py, y el nombre de la variable (aplicacion) debe hacer referencia a una función, normalmente a la función main de nuestra aplicación, que debe encontrarse especificada en el módulo.
El comando gunicorn ofrece una extensa lista de opciones para configurar su comportamiento, pero las que he utilizado y que me han parecido más interesantes son:
--config FILE: ruta hacia el fichero de configuración.--bind ADDRESS: es posible especificar tantoHOST:PUERTOcomo la ruta a un socket conunix:RUTA_SOCKET.
Ejemplo:--bind unix:///home/mviera/gunicorn/gunicorn.sock--workers INT: número de procesos workers que se arrancarán para servir las peticiones.--max-requests INT: número máximo de peticiones que servirá un worker antes de ser reiniciado.--debug: activa el debug en el servidor.--log-file: fichero de log.
Un ejemplo de ejecución sería:
$ gunicorn modulo:application --workers 2 \ --bind unix:///home/mviera/gunicorn/gunicorn.sock \ --max-requets 1000 --log-file /home/mviera/gunicorn/gunicorn.log
Podeis consultar el resto de opciones en la documentación de configuración de Gunicorn.
Por último y para terminar con el despliegue, una vez que tengamos a Gunicorn sirviendo nuestra aplicación lo correcto sería instalar un servidor web que actúe como proxy HTTP hacia nuestra aplicación, yo como siempre recomiendo utilizar Nginx :-)
Y hasta aquí lo que he aprendido sobre Gunicorn, un breve resumen de la documentación oficial.
Conclusiones
Gunicorn me ha sorprendido no solo por su fácil instalación, a diferencia de uWSGI que necesita ser compilado; sino también por su fácil configuración y uso.
Como dije al principio, cuenta con una serie de hooks que permite ejecutar código Python en los diferentes puntos de ejecución: on_start, when_ready, on_reload, pre_fork, post_fork, etc. Esto también me ha gustado mucho, aunque no los he llegado a probar.
La verdad es que Gunicorn me ha dejado con un muy buen sabor de boca aunque no he llegado a probarlo en un entorno real de producción para ver cómo se comporta. De momento seguiré con uWSGI hasta que tenga la ocasión de utilizar Gunicorn ;-)
Un saludo.
PD: En el próximo post explicaré cómo desplegar Trac utilizando Gunicorn!




aaloy
Hola Manuel,
Nosotros (http://apsl.net) estamos utilizando Gunicorn en entornos de producción desde hace bastante tiempo y no tenemos queja alguna.
uWSGI por otra parte ofrece bastantes facilidades a la hora de administrar muchas aplicaciones y el consumo de memoria es algo menor que Gunicorn.
Ambos son perfectamente capaces de soportar la carga que requieren la mayoría de aplicaciones, así que la utilización de uno u otro depende de las características de tu aplicación o aplicaciones.
Nosotros estamos cambiando a uWSGI en las nuevas aplicaciones, pero seguimos manteniendo y actualizando gunicorn en las más antiguas.
mviera
Hola Antoni,
Interesante! gracias por la información! :-)
Yo hace ya más de un año que utilizo uWSGI para los despliegues y la verdad es que estoy bastante contento con el rendimiento, sobre todo viniendo de mod_python y FastCGI :-D
Por cierto, ¿qué servidor web utilizáis como frontend? Yo suelo utilizar Nginx y también estoy muy contento con su rendimiento, aunque aún le faltan muchos módulos que Apache2 sí que tiene y que son necesarios y útiles, autenticación contra LDAP, etc, etc.
Estoy muy contento con el Nginx + uWSGI, aunque a ver si saco algo de tiempo y hago un mini benchmark entre uWSGI y Gunicorn :-)
Gracias por el comentario! Encantado de leerte!
Un saludo.
Danny Navarro
Qué bueno leer esta clase de entradas de blog en español.
Otra de las características cruciales de Gunicorn es que puedes configurar los workers de Gunicorn para que sean gevent o eventlet workers. Además del aumento de rendimiento que supone esto, también te permite manejar eventos en el lado del servidor. https://github.com/benoitc/gunicorn/tree/master/examples/websocket
mviera
Hola Danny!
Me alegra verte por aqui ;-)
uWSGI también tiene una implementación de Green Threads a partir de la versión 0.9.5, llamada uGreen. Según la documentación [1] es muy parecido a python greenlet, pero la verdad es que tampoco lo he probado… Tendré que estirar un poco más los días para sacar tiempo y probarlo :-)
Gracias por comentar! Un saludo!
[1] http://projects.unbit.it/uwsgi/wiki/uGreen