miércoles, 26 de noviembre de 2014

Balanceo de Carga y Alta Disponibilidad en un Webserver con Apache y Perl (versión 2)



En este enlace http://redes-seguridad.blogspot.com.ar/2014/07/balanceo-de-carga-y-alta-disponibilidad.html les mostré como hacer el balanceo aleatorio entre 2 webservers, detectaba si uno de ambos estaba caído enviaba las peticiones web's al otro:

Pero quedaba pendiente verificar el "CPU load" antes de hacer la redirección y basarse en la carga en vez de redireccionar aleatoria-mente. Con esta última versión del script cubrimos ese tema:


Escenario:

Tenemos 2 servidores web, cada uno escuchando en el mismo puerto la misma aplicación.

El script irá distribuyendo al webServer que tenga menor "Carga de CPU", en caso que alguno tenga el puerto bajo, es decir que la aplicación esté baja reenviará las peticiones al webserver que esté arriba.

Es decir, pueden ocurrir las diferentes situaciones:

1) Ambos servidores UP y con la aplicación ok, testea al de menor uso de CPU y redirige la petición a este.
2) Servidor1 caído ó la aplicación DOWN => redirecciona al Servidor2.
3) Servidor2 caído ó la aplicación DOWN => redirecciona al Servidor1.
4) Ambos Servidores caidos, en mi caso no hago nada, pero puedo mostrar algún mensaje que deseen.



Script:


#!/usr/bin/perl

##Descomentar la siguiente linea si desea ver lo que hace en vez de ejecutar la redirección:
#print "content-type: text/html \n\n";

##Escanea al WebServer1 el puerto 80 y verifica si está abierto, guarda en la variable $VAL1 si el comando fue correcto ó no:
$result1 = `nmap -sT -P0 WebServer1-p 80|grep open`;
$VAL1=$?;

##Escanea al WebServer2 el puerto 80 y verifica, idem al anterior, pero guarda el valor en $VAL2:
$result2 = `nmap -sT -P0 WebServer2 -p 80|grep open`;
$VAL2=$?;

##Concatena los valores de $VAL1 y $VAL2 en $VAL:
$VAL=$VAL1.$VAL2;

##Descomento las siguientes líneas si deseo ver los valores que obtienen las variables, recuerde que también debe descomentar la línea del conten-type que aparece al inicio del script:
#print "VAL1: ", $VAL1, "";
#print "VAL2: ", $VAL2, "";
#print "VAL:   ", $VAL,   "";

##Para pruebas hardcodeadas modificar y descomentar las siguientes variables:
## El valor 00     => ambos servidores escuchan, ver por CPU cual es el de menor uso
## El valor 0256   => redirige a WebServer01 (WebServer01 caido)
## El valor 2560   => redirige a WebServer02 (JDE05 caido)
## El valor 256256 => ambos webservers caido
#$VAL="00";
use Switch;
switch ($VAL)
{
 case "00"
 {
  ##Tener en cuenta que con el usuario de root no funciona, por eso utilicé el de apache, recuerde generar las keys ssh para el usuario www-data:
  my $CPU_SERVER1 = `ssh www-data'\@'ServerNagios /ruta/al/script/de/nagios/libexec/check_nt -H WebServer1 -v CPULOAD -l 5,80,90 | cut -d' ' -f3 | cut -d'%' -f1`;

  my $CPU_SERVER2 = `ssh www-data'\@'ServerNagios /ruta/al/script/de/nagios/libexec/check_nt -H WebServer2 -v CPULOAD -l 5,80,90 | cut -d' ' -f3 | cut -d'%' -f1`;

  ##Descomentar si desea ver valores, recuerde descomentar la content-type al inicio del script
  #print "SERVER1: ", $CPU_SERVER1, " ";
  #print "SERVER2: ", $CPU_SERVER2, " ";

  ##Evalua quien tene menor uso de CPU: 
  if ( $CPU_SERVER1 > $CPU_SERVER2)
  {
   ##Tener en cuenta que esto redirecciona, si descomenta el content-type lo mostrará por pantalla   
   print "Location: http://WebServer2:80/aplicacion\n\n";
  }
  else
  {
   ##Tener en cuenta que esto redirecciona, si descomenta el content-type lo mostrará por pantalla   
   print "Location: http://WebServer1:80/aplicacion\n\n";
  }
 }
 case "0256"    { print "Location: http://WebServer1:80/aplicacion\n\n"; }
 case "2560"    { print "Location: http://WebServer2:80/aplicacion\n\n"; }
 case "256256"  { print "Ningun webserver (WebServer1 y WebServer2) escucha en el puerto 80" }
 else           { print "Valor no contemplado en el Perl de Load Balance" }
}