¡Hola a todos! Ya con anterioridad se ha mencionado en nuestro blog a Gunicorn, el también conocido como Green Unicorn (Unicornio Verde). Este es un servidor HTTP para Python que soporta WSGI, Django y Paster de forma nativa; consume pocos recursos en ejecución y es bastante rápido.

small_gunicorn

 

Gunicorn nos permite administrar las peticiones simultáneas que nuestra aplicación recibe y que 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 (y otros) que lo hacen más extensible.

 

 Instalación

Para suerte nuestra este unicornio a diferencia del de Silvio Rodríguez, no está perdido, más bien está disponible por muchas vías. Podemos instalarlo en Debian y derivados ejecutando

sudo apt-get install gunicorn

o usando pip

pip install gunicorn

 

Puede que también se necesite instalar Eventlet o Gevent si se espera que el código de la aplicación pueda hacer pausas durante largos períodos de tiempo durante el procesamiento de solicitudes. Ver la documentación para obtener más información sobre cuándo considerar usar uno de los tipos de trabajadores suplentes.

pip install eventlet  # Para workers eventlet
pip install gevent    # Para workers gevent
pip install greenlet  # Requerido para ambos

 

Uso

Después de instalado ya podemos tener acceso a los comandos disponibles en Gunicorn que son:

  • gunicorn: utilizado para servir aplicaciones WSGI.
  • gunicorn_django: utilizado para servir aplicaciones Django.
  • gunicorn_paster: para frameworks compatibles con Paster como Pyramid, Pylons, TurboGears 2, …

 

gunicorn [OPTIONS] APP_MODULE

Donde APP_MODULE se define como $(MODULE_NAME):$(VARIABLE_NAME). El nombre del módulo puede ser la ruta completa del fichero y el nombre de la variable se refiere a la variable que guarda la aplicación WSGI.

Un ejemplo de uso sería el siguiente:

gunicorn --workers 5 test:application

Entre las opciones más relevantes están:

  • -c FILE, --config FILE. La ruta del fichero de configuración o módulo Python.
  • -b ADDRESS, --bind ADDRESS. Un string de la forma: ‘HOST’, ‘HOST:PORT’, ‘unix:PATH’. Un IP es un HOST válido.
  • -w INT, --workers INT. El número de workers, que por defecto es 1.
  • -k STRING, --worker-class STRING. El tipo de worker, que por defecto es sync pero pueden ser: sync, eventlet, gevent y tornado. Personalmente prefiero Gevent. 😀
  • --worker-connections INT. La cantidad máxima de clientes simultáneos. Por defecto este valor es de 1000.
  • -u USER, --user USER. El usuario que ejecutará el proceso. Este valor puede ser el uid o el nombre del usuario.
  • -g GROUP, --group GROUP. El grupo que ejecutará el proceso. Este valor puede ser el gid o el nombre del grupo.

El archivo de configuración debe ser un archivo de código fuente Python válido. Sólo tiene que ser legible desde el sistema de archivos. Más específicamente, no necesita ser importable. Cualquier Python es válida. Sólo considere que este se ejecutará cada vez que se inicia Gunicorn (incluso cuando usted señala Gunicorn para recargar).

Para establecer un parámetro, simplemente asignar a la misma. No hay una sintaxis especial. Los valores suministrados por el usuario serán utilizados para los valores de configuración.

import multiprocessing

bind = "127.0.0.1:8000"
workers = multiprocessing.cpu_count() * 2 + 1

 

Workers

Con respecto al número de workers es válido aclarar que no debe asociarse con el número de clientes que espera tener. Gunicorn sólo debería necesitar 4-12 procesos de trabajo para manejar cientos o miles de peticiones por segundo.

Gunicorn se basa en el sistema operativo para proporcionar todo el equilibrio de la carga cuando tramita las solicitudes.

La cantidad de workers a usar dependerá de las condiciones en las que se ejecutará tu aplicación. Una receta (no un dogma) que encontré (en la documentación oficial) y me gustó mucho nos dice que esta cantidad generalmente se recomienda que sea igual a la (cantidad de CPUs * 2) + 1.

Según esta receta si nuestro server tuviera:

  1. (1 CPU   * 2) + 1 = 3 workers
  2. (2 CPU’s * 2) + 1 = 5 workers
  3. (3 CPU’s * 2) + 1 = 7 workers
  4. (4 CPU’s * 2) + 1 = 9 workers
  5. (5 CPU’s * 2) + 1 = 11 workers
  6. (6 CPU’s * 2) + 1 = 13 workers
  7. y así hasta el infinito y mas allá!

 

Recuerden que Gunicorn es para servir todo lo dinámico de nuestro proyecto en nuestro server. Personalmente recomiendo usarlo en combinación con Nginx (un servidor que nos sirve de proxy HTTP) para servir los ficheros estáticos y Gevent para atender las peticiones de forma asincrónica. ¡Hasta la próxima!

 

Más información: Documentación Gunicorn.