Nginx: Balanceo de carga HTTP en Linux

Aprendemos a utilizar el servidor web Nginx para facilitar balanceo de carga para HTTP en GNU/Linux Dicho balanceo de carga nos permite distribuir de manera eficiente las solicitudes de servicio entrantes o el tráfico de en red, en un grupo de servidores previamente definidos.

El balanceo o equilibrio de carga tiene varias ventajas, entre las que se encuentra una mayor disponibilidad de aplicaciones a través de la redundancia y una mayor fiabilidad y escalabilidad. Por ejemplo, podemos agregar más servidores en el pull (conjunto de nodos) cuando aumenta el tráfico. Entre otras cosas también nos ofrece un mejor rendimiento de la aplicación.

Podemos configurar Nginx para balancear la carga de red entrante y la carga de trabajo, tal y como hemos comentado, entre un grupo de servidores de aplicaciones, devolviendo la respuesta del servidor seleccionado al correspondiente cliente.

Existen varios métodos de balanceo de carga:

  • round-robin: que distribuye las solicitudes a los servidores de aplicaciones de forma redonda. Es el que se usa por defecto.
  • Selección del menos ocupado: asigna la siguiente solicitud a un servidor menos ocupado (el servidor con el menor número de conexiones activas
  • ip-hash: donde se utiliza una función hash para determinar qué servidor se debe seleccionar para la próxima solicitud en función de la dirección IP del cliente. Este método permite la persistencia de la sesión (vincular un cliente a un servidor de aplicaciones en particular).

Además, podemos utilizar la configuración del servidor para influir en los algoritmos del balanceo de carga de Nginx, a nivel más avanzado. También admite comprobaciones de estado para marcar un servidor, por ejemplo, como fallido, durante un tiempo dado.

En este ejemplo vamos a utilizar un único frontal, con dos servidores en la parte del backend, con el rol de servidor de aplicaciones.

Requisitos previos

Hemos de contar con este entorno:

  • Balanceo de carga: 192.168.0.200
  • Servidor de aplicación 1: 192.168.0.101
  • Servidor de aplicación 2: 192.168.0.102

Lo ideal es que esta información ya esté configurada en nuestro servidor DNS correspondiente. También podemos añadir esta información al fichero /etc/hosts

Por ejemplo:

192.168.0.200 frontal.bitsandlinux.com
192.168.0.101 backend1.bitsandlinux.com
192.168.0.102 backend2.bitsandlinux.com

Instalar y configurar el balanceo de carga con Nginx

Como no podía ser de otra manera, en el equipo que cumplirá con el rol de frontal web, instalaremos Nginx:

# En el caso de Debian y derivadas
sudo apt install nginx
# En el caso de RHEL, Centos y Fedora
sudo dnf install nginx

Una vez instalado debemos crear el fichero de configuración correspondiente en /etc/nginx/conf.d/loadbalancer.conf. Aquí podemos utilizar el editar que más nos plazca:

sudo vi /etc/nginx/conf.d/loadbalancer.conf

Y añadimos:

upstream backend {
        server 192.168.0.101;
        server 192.168.0.102;
    }
 
    server {
        listen      80 default_server;
        listen      [::]:80 default_server;
        server_name frontal.bitsandlinux.com;
 
        location / {
            proxy_redirect      off;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    Host $http_host;
        proxy_pass http://backend;
    }
}

En la configuración, la directiva «proxy_pass» (que debe especificar dentro de una ubicación, / en este caso) se utiliza para pasar una solicitud a los servidores proxy HTTP indicados, utilizando el término «backend«, en la directiva ascendente (utilizada para definir un grupo de servidores)

Además, las solicitudes se distribuirán entre los servidores utilizando el mecanismo round-robin que hemos comentado antes.

Para modificar el sistema de conexión, debemos utilizar la primera sección, por ejemplo:

upstream backend {
        least_conn;
        server 192.168.0.101;
        server 192.168.0.102;
    }

O bien:

upstream backend {
        ip_hash;
        server 192.168.0.101;
        server 192.168.0.102;
    }

También podemos influir en las decisiones que toma el sistema, indicando el paso de cada nodo de backend. Utilizando la siguiente configuración, si hay ocho solicitudes de clientes, el servidor de aplicaciones 192.168.0.101 se le asignarán seis solicitudes y las dos restantes irán al nodo 192.168.0.102

upstream backend {
        server 192.168.0.101    weight=6;
        server 192.168.0.102;
    }

Guardamos el fichero y salimos. Podemos validar los cambios de la siguiente manera:

sudo nginx -t

Añadimos el servicio al arranque y lo encendemos:

sudo systemctl restart nginx
sudo systemctl enable nginx

Para obtener más información de como operar con Nginx, puedes consultar esta entrada:

Arranque y parada de un servidor web NGINX en Linux

La verdad es que tiene muchas posibilidades este tipo de balanceo de carga, ya que también lo podemos utilizar, por ejemplo, para conectar con diferentes instancias de una base de datos con MariaDB y Galera; también otro ejemplo clásico sería tener en la parte de backend, servidores de aplicación con Red Hat JBoss u Oracle WebLogic.

Y es todo, espero que esta información os pueda ser de utilidad en algún momento. Nos vamos leyendo.

Fuentes consultadas:

Nginx.org – Using nginx as HTTP load balancer
Tecmint.com – How to Use Nginx as an HTTP Load Balancer in Linux