Load Balancing con NGINX


Load Balancing round-robin o ip_hash

NGINX soporta la realización de balanceo de carga mediante la directiva proxy_pass, salvo que en lugar de dirigir las peticiones a una URL concreta, lo hacemos a un upstream que agrupa a varios servidores.

La definición de upstream nos permite definir balanceos por round robin (alternando peticiones entre los diferentes servidores que componen el upstream) o por ip de origen, añadiendo la directiva ip_hash; dentro del upstream:

# cat /etc/nginx/sites-enabled/dominio.conf:

server {
    listen   80;
    server_name dominio.com;

    access_log  /var/log/nginx/dominio.access.log;
    root   /var/www/dominio/;

    upstream apaches_roundrobin
    {
        server 172.16.1.2:81 ;
        server 172.16.1.3:81;
    }

    upstream apaches_por_ip
    {
        ip_hash;
        server 172.16.1.2:81;
        server 172.16.1.3:81;
    }

    location / 
    {
        proxy_pass http://apaches_roundrobin;
        include /etc/nginx/proxy.conf;
    }
}

# cat /etc/nginx/proxy.conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 16k;
proxy_buffers 32 64k;
proxy_busy_buffers_size 128k;

La desventaja del balanceo ip_hash es que todos los usuarios detrás de un proxy o de un NAT serán dirigidos al mismo backend, lo que puede suponer que el balanceo no sea equilibrado. Para evitar esto, los balanceadores modernos permiten balancear usando una cookie, que sí que identifica a los usuarios finales.

A partir de la versión 1.2 de NGINX ya es posible utilizar conexiones con keepalive entre el nginx y los backends del upstream de forma que se realice una conexión con una persistencia de múltiples peticiones HTTP en lugar de abrir una conexión nueva cada vez.

Para especificar a nginx que use keepalive, debemos modificar nuestro upstream añadiendo la directiva keepalive y un tiempo de mantenimiento de la conexión en segundos:

upstream apaches_roundrobin
{
    server 172.16.1.2:81;
    server 172.16.1.3:81;
    keepalive 3;
}

A la hora de hacer el proxy_pass, tendremos que indicar que la conexión entre nginx y los backends sea HTTP 1.1 y eliminar la cabecera Connection para evitar que se pase al backend la que indica el usuario:

location / 
{
    proxy_pass http://apaches_roundrobin;
    include /etc/nginx/proxy.conf;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}


Opciones adicionales para los backends

Las siguientes opciones adicionales están disponibles en la definición de server dentro del upstream:


  • weight = NUMBER → Especificar un peso para el servidor (por defecto es 1).
  • max_fails = NUMBER → Especificar un número de intentos de comunicación erróneos en "fail_timeout" segundos para considerar al servidor no operativo (por defecto es 1, un valor de 0 lo desactivaría).
  • fail_timeout = TIME → Tiempo en el que deben ocurrir "max_fails" intentos fallidos de conexión para considerar al servidor no operativo. Por defecto es 10 segundos.
  • down → Marca el servidor como permanentemente offline (para ser usado con ip_hash;).
  • backup → Sólo usa este servidor si alguno de los otros servidores no-backup está caído u ocupado. No es compatible con la directiva ip_hash;


Por ejemplo:

upstream  backend  {
  server   backend1.example.com    weight=1;
  server   backend2.example.com    weight=3;
  server   backup.example.com      backup;
  server   127.0.0.1:8080          max_fails=3  fail_timeout=30s;
  server   unix:/tmp/backend3;
}



<Volver a Página de NGINX>