Introducción

nginx [engine x] es un servidor proxys inverso HTTP (reverse proxy) y tambien un mail proxy escrito por Igor Sysoev. A la fecha ya lleva mas de 5 años corriendo en sitios de trafico alto.

Caracteristicas básicas HTTP

  • Brindar archivos estaticos y de indice (autoindexing), cache de open file descriptors.
  • Acelera el proceso de proxy inverso con cache. Balanceo de carga y fail-over simple.
  • Soporte acelerado de servidores remotos FastCGI con cache.Balanceo de carga y fail-over simple.
  • Arquitectura modular. Filtros, GZIP, chunked responses, XSLT, filtro de redimencionado de imagenes, Server Side Include (SSI) entre varios servidores remotos.
  • Soporte SSL y TLS SNI

Otras caracteristicas HTTP

  • Servidores virtuales basados en IP o nombres.
  • Soporte para conexiones keep-alive.
  • Configuración flexible.
  • Reconfiguración y actualizaciones sin interrupción de servicio.
  • Formateo de logs y rotación rápida.
  • Redirección de codigos de error 3xx-5xx
  • Modulo Rewrite.
  • Control de acceso basado en IP y Basic HTTP AUTH.
  • Metodo PUT, DELETE, MKCOL, COPY y MOVE soportados.
  • FLV streaming;
  • Limite de velocidad/BW.
  • Limitacion de conexiones desde un mismo cliente.
  • Perl embebido.

Experiencia personal

Decidi escribir un post sobre Nginx debido a mi experiencia personal con el mismo en la compañia donde actualmente trabajo. En la misma nuestros clientes usan un gran sistema web para el monitoreo de moviles (PHP+Mapserver), con muchas aplicaciones repartidas entre varios servidores. En el pasado se utilizaba Apache con mod_proxy para poder redireccionar pedidos a otros servidores desde el mismo dominio. Teniamos aproximadamente 180 sesiones (Threads) de apache corriendo constantemente y era muy facil pisar el techo de los 250 (Maximo debido a limitaciones de memoria del servidor). Por ello se decide instalar nginx on-the-top, incluso hoy en nuestro ambiente de produccion nginx se encuentra corriendo en el mismo servidor que apache. Con Nginx se logro reducir a 25 las sesiones/threads concurrente en apache.

Instalación

La instalacion es bastante sencilla (http://wiki.nginx.org/Install). Personalmente uso Gentoo en mis servidores por lo que la instalacion la realizo desde el gestor de paquetes emerge

emerge -uv nginx

Configuración

No es el objetivo hoy ir muy profundo en la configuración de nginx, la verdad que la wiki en ingles esta bastante completa y posee ejemplos de todo tipo (http://wiki.nginx.org/Configuration)

El archivo de configuración por default se ubica en /etc/nginx/nginx.conf y se divide en bloques. El mas importante para nosotros en este momento es el bloque http { }. Alli tenemos todas las configuraciones referentes al protocolo http, time outs, errores, limites, etc. Dentro del mismo podemos tener 1-n bloques server { }. Los mismos son similares a los bloques VirtualHost de apache.

server {
  listen          80;
  server_name     www.domain.com;

  index           index.html;
  root            /home/domain.com
}

Cada VirtualHost/Server podemos hacerlo escuchar en el puerto que nosotros deseemos con el parametro listen. server_name especifica el virtualHost al que hacemos referencia en este bloque. Podemos agregar mas de un dominio/host separados por espacio.

El parametro index indica el archivo que hara de indice y el parametro root es el DocumentRoot donde se ubicaran todos los archivos del host.

Otra característica interesante de la configuración es el parámetro include que nos permite incluir otros archivos dentro de la configuración. Esto permite armar una configuración simil a la de apache y sus virtualhosts.

Con la configuración de ejemplo ya tendriamos al dominio “www.domain.com” contestando peticiones y obteniendo el contenido desde /home/domain.com. Siempre contenido estatico.

Usos

Servidor Proxy inverso & Fail-Over

La principal caracteristica de NGINX es la de un reverse proxy server. Esto permite que el cliente haga una peticion a nuestro srevidor proxy y el mismo decida quien responde a esta peticion. Para esta funcion de utiliza el modulo HTTPProxyModule de Nginx que nos da el parametro proxy_pass (http://wiki.nginx.org/HttpProxyModule#proxy_pass). Este parametro debe ir dentro del bloque location (http://wiki.nginx.org/HttpCoreModule#location). El mismo básicamente nos permite especificar una ubicación especifica dentro de un server (Similar a apache).

El parametro proxy_pass permite redireccionar la peticion a otra URL, la misma puede ser una IP, DNS o bien un upstream server. Estos ultimos se definen en el bloque upstream dentro del bloque http.

upstream server_one {
	server 172.16.102.3;
	server 172.16.102.11 backup;
}

upstream server_two {
	server 172.16.102.11;
	server 172.16.102.3 backup;
}

server {
  listen          80;
  server_name     www.domain.com;
  location /web/ {
    proxy_pass http://server_one;
  }

  location /images/ {
    proxy_pass http://server_two;
  }
}

En la configuración de ejemplo he definido dos upstream servers, ambos con dos servidores internamente, uno como activo y el otro servidor como backup. Esto significa que el segundo no respondera ninguna petición hasta que el primero no caiga.

Luego dentro de nuestro server de ejemplo he definido dos locations (web y images) que seran atendidas por los dos upstream servers que definimos anteriormente.

Asi si accediéramos a http://www.domain.com/web/archivo.php el mismo inicialmente seria solicitado al servidor web http://172.16.102.3/web/archivo.php. Si este estuviera caido, nginx automáticamente redireccionaria las peticiones a http://172.16.102.11/web/archivo.php. Lo mismo sucede con /images/.

Balanceo de carga

Para realizar balanceo de carga la configuración es igual a la anterior, el único que cambio que necesitamos hacer es quitar el parámetro backup del ultimo servidor del bloque upstream en cuestión. Adicionalmente podemos utilizar el parametro weight para darle mas peso a un servidor que a otro y realizar un balanceo de carga mas controlado.

upstream server_one {
	server 172.16.102.3 weight=2;
	server 172.16.102.11;
}

En el ejemplo tendriamos 2 de cada 3 peticiones siendo enviadas a 172.16.102.3 y la ultima restante a 172.16.102.11. Esto tambien incluye failover, cuando nginx detecta que un servidor esta fuera de linea automaticamente lo remueve del pool de servidores. El mismo es chequeado periodicamente para comprobar si ha vuelto a estar online.

Resumen

Nginx es una aplicación muy potente que nos da fail-over, balanceo de carga y escabilidad ya que podemos agregar nuevos servidores on-the-fly. Personalmente he testeado nginx con 1024 conexiones concurrentes y no superaba los 250 MB de ram consumidos. Agregando mas worker_process tranquilamente podriamos responder muchas mas peticiones.

Adicionalmente posee un sistema de cacheo muy configurable, actualmente utilizo NGINX en las oficinas remotas de la compañia. Esto me permite cachear localmente todo el contenido estatico (Imagenes, JavaScripts, html, css, etc) y por el enlace de datos (Internet o MPLS) solicitar las paginas dinámicas PHP que necesitan acceso a nuestra base de datos principal. Asi mantengo el procesamiento centralizado, ahorro ancho de banda y aumento la velocidad de respuesta notablemente. Prometo tocar mas en profundo esta solución en las próximas semanas, con ejemplos y todo.

Duda o comentarios? Abajo podes comentar.