Configurar Nginx como balanceador de carga (Load Balancing)

Para configurar Nginx como balanceador de carga primero debemos configurar el mismo como servidor de proxy inverso, ver Configurando Nginx como Proxy inverso, la única diferencia es que en este caso la configuración del proxy inverso no vinculara directamente con un host, sino que apuntará a la configuración de un cluster de servers indicados con la directiva upstream sobre el mismo archivo de configuración de Nginx.

Upstream: Esta directiva describe un conjunto de servidores, que pueden ser utilizados con las directivas PROXY_PASS y fastcgi_pass como una sola entidad. Se puede configurar un servidor en puertos diferentes y, además, es posible utilizar simultáneamente un servidor que escuche en TCP y sockets Unix.
Procedemos a detallar la configuración de Neginx como Load Balancing.
Asumimos que Nginx ya está configurado y que están creados los siguientes directorios:

  •  sites-available
  •  sites-enabled

Creamos un archivo de configuración correspondiente al dominio sobre el cual se hará balance de carga.

vim /etc/nginx/sites-available/big.server.com.conf

Y le agregamos el siguiente contenido correspondiente a la configuración.

upstream big_server_com {
	server 192.168.7.20:8801;
	server 192.168.7.20:8802 weight=1;
	server 192.168.7.20:8803 weight=2 max_fails=2;
	server 192.168.7.20:8804 weight=2 max_fails=2 fail_timeout=20;
	server 192.168.7.20:8805 weight=4;
	server 192.168.7.20:8806 weight=4 fail_timeout=4;
	server 192.168.7.20:8807 weight=2 fail_timeout=20;
}

server { # simple load balancing
	listen          	80;
	server_name     	big.server.com;
	access_log      	/var/log/nginx/big.server.access.log main;
	access_log 		/var/log/nginx/big.server.cache.log cache;
	error_log   		/var/log/nginx/big.server.error.log error;

	location / {
				proxy_pass      http://big_server_com;
	}
}

  • Weight=[number]: Especifica una ponderación entre los diferentes servidores configurados, el valor por defecto es 1 y para ponderar un host mas que otro se incrementa su valor. Un servidor con una ponderación de 2 recibirá el doble de tráfico que uno con una ponderación por defecto y así sucesivamente.
  • Max_fails=[number]: Esta variable especifica el número de intentos infructuosos de comunicación con el host antes de ser considerado no operativo. Para evitar que los servidores que alguna fueron marcados como inactivos, aunque se encuentra fuera de cobertura, establecer este valor a 0. El valor predeterminado para max_fails es 1.
  • Fail_timeout=[tiempo en segundos]: Este argumento determina el lapso de tiempo en que el número de intentos fallidos max_fails debe ocurrir con el fin de marcar un componente del servidor fuera de servicio. Tener en cuenta, para los servidores que devuelven un mensaje de error 404, se considera operativo y este valor no afecta a los tiempos de espera para las conexiones del proxy establecido.

En el ejemplo anterior, hay siete componentes de servidor (hosts configurados) que se ejecutan en los puertos únicos en el servidor 192.168.7.20 y comprenden el appcluster upstream. Los componentes que se ejecutan en los puertos 8801 y 8802 son tratados de forma idéntica por Nginx, ya que el valor predeterminado para el weight es de 1. Los componentes que se ejecutan en los puertos 8803, 8804, 8807 recibirán un tráfico de dos veces mayor que los dos primeros. Los componentes, 8805 y 8806 recibirán cuatro veces más tráfico que 8801 y 8802 y el doble que los componentes 8803, 8804 y 8807.

Los componentes en los puertos 8801, 8802, 8805, 8806 y 8807 sólo pueden rechazar una conexión antes de ser marcado como fuera de servicio (no operativos). Para los componentes 8803 y 8804 se les permite fallar dos veces antes de ser marcado como fuera de servicio. Por defecto, todos los componentes tienen su “fail counter” reset cada 10 segundos, que cubre los componentes de 8801, 8802, 8803 y 8805. Los componentes, 8804 y 8807 tienen sus fail counters reset cada 20 segundos, mientras que 8806 tiene su fail counter reset cada 4 segundos. Con estos argumentos, se puede usar nginx para gestionar el comportamiento y distribución de carga a través de un cluster de servidores.

upstream appcluster {
   ip_hash;
   server 192.168.1.80:8801 down;
   server 192.168.1.80:8802;
}

ip_hash se utiliza para tratar de asegurar que los requests procedentes de una única dirección IP permanecerán unidos a un componente específico del clúster. Si un componente de servidor es inaccesible, Nginx dirigirá esas conexiones a un componente alternativo. Si un servidor tiene que estar offline durante un período prolongado de tiempo, debemos añadir el argumento down como en la entrada 192.168.1.80:8801 del ejemplo anterior para evitar la pérdida de conexiones al intentar acceder a un componente del servidor que está offline.