WebSphere Load Balancer para IPv4 e IPv6
             Sistema operativos: AIX, HP-UX, Linux, Solaris, Windows

             Personalice la tabla de contenidos y los resultados de la búsqueda

Ejemplo: implementación de un asesor de dos puertos

En el ejemplo siguiente se muestra cómo implementar un asesor de dos puertos. En este ejemplo de asesor personalizado se muestra la capacidad de detectar anomalías de un puerto de un servidor basándose en su propio estado y en el estado de otro daemon del servidor que se ejecuta en otro puerto de la misma máquina servidor.

Por ejemplo, si el daemon HTTP del puerto 80 deja de responder, quizá prefiera también detener el tráfico de direccionamiento al daemon SSL en el puerto 443.

El asesor es más radical que los asesores estándar, porque considera cualquier servidor que no envía una respuesta que ha dejado de funcionar y lo marca como inactivo. Los asesores estándar consideran que los servidores que no responden son muy lentos. Este asesor marca un servidor como inactivo para los puertos HTTP y SSL basándose en la falta de respuesta por parte de cada puerto.

Para utilizar este asesor personalizado, el administrador inicia dos instancias del asesor: una en el puerto HTTP y la otra en el puerto SSL. El asesor crea una instancia de dos tablas hash globales estáticas, una para HTTP y otra para SSL. Cada asesor intenta comunicarse con su daemon del servidor y almacena los resultados de este suceso en la tabla hash. El valor que cada asesor devuelve a la clase del asesor base depende de la capacidad de comunicarse con su propio daemon del servidor y la capacidad del asesor asociado de comunicarse con su daemon.

Se utilizan estos métodos personalizados.
Se detectan las siguientes condiciones de error:
Este ejemplo está grabado para enlazar los puertos 80 para HTTP y 443 para SSL, pero se puede adaptar a cualquier combinación de puertos:
package CustomAdvisors;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Date;
import com.ibm.internet.lb.advisors.*;
import com.ibm.internet.lb.common.*;
import com.ibm.internet.lb.manager.*;
import com.ibm.internet.lb.server.SRV_ConfigServer; 

//--------
// Definir el elemento de la tabla para las tablas hash utilizadas en este asesor personalizado 

class ADV_nte implements Cloneable {
  private String sCluster;
  private int iPort;
  private String sServer;
  private int iLoad;
  private Date dTimestamp;

//--------
// constructor 

  public ADV_nte(String sClusterIn, int iPortIn, String sServerIn,
                 int iLoadIn) {
    sCluster = sClusterIn;
    iPort = iPortIn;
    sServer = sServerIn;
    iLoad = iLoadIn;
    dTimestamp = new Date();
  }

//--------
// comprobar si este elemento es actual o ha caducado
  public boolean isCurrent(ADV_twop oThis) {
    boolean bCurrent;
    int iLifetimeMs = 3 * 1000 * oThis.getInterval();     // establecer el tiempo de vida como
                                                          // 3 ciclos del asesor
    Date dNow = new Date();
    Date dExpires = new Date(dTimestamp.getTime() + iLifetimeMs); 

    if (dNow.after(dExpires)) {
      bCurrent = false;
    } else {
      bCurrent = true;
    } return bCurrent;
  } 

//--------
// objetos usuario de valor 

 public int getLoadValue() { return iLoad; } 

//--------
// clonar (impide el daño entre las hebras) 

 public synchronized Object Clone() {
   try {
     return super.clone();
   } catch (cloneNotSupportedException e) {
     return null;
    }
  } 

} 

//--------
// definir el asesor personalizado

public class ADV_twop extends ADV_Base
   implements ADV_MethodInterface, ADV_AdvisorVersionInterface {
   static final int ADV_TWOP_PORT_HTTP = 80;
   static final int ADV_TWOP_PORT_SSL = 443; 

   //--------
   // definir las tablas para mantener la información histórica específica del puerto 

   static HashTable htTwopHTTP = new Hashtable();
   static HashTable htTwopSSL = new Hashtable();
   static final String ADV_TWOP_NAME = "twop";
   static final int ADV_TWOP_DEF_ADV_ON_PORT = 80;
   static final int ADV_TWOP_DEF_INTERVAL = 7;
   static final String ADV_HTTP_REQUEST_STRING =
      "HEAD / HTTP/1.0\r\nAccept: */*\r\nUser-Agent: " +
      "IBM_LB_Custom_Advisor\r\n\r\n";

   //--------
   // crear la matriz de bytes con el mensaje client hello SSL 

   public static final byte[] abClientHello = {
     (byte)0x80, (byte)0x1c,
     (byte)0x01,                                // client hello
     (byte)0x03, (byte)0x00,                    // versión SSL
     (byte)0x00, (byte)0x03,                    // longitud específica de cifrado (bytes)
     (byte)0x00, (byte)0x00,                    // longitud de ID de sesión (bytes)
     (byte)0x00, (byte)0x10,                    // longitud de datos de identificación (bytes)
     (byte)0x00, (byte)0x00, (byte)0x03,        // especificación de cifrado
     (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20,    // datos de identificación
     (byte)0xFD, (byte)0x3A, (byte)0x3C, (byte)0x18,
     (byte)0xAB, (byte)0x67, (byte)0xB0, (byte)0x52,
     (byte)0xB1, (byte)0x1D, (byte)0x55, (byte)0x44, (byte)0x0D, (byte)0x0A }; 

  //--------
  // constructor 

  public ADV_twop() {
    super(ADV_TWOP_NAME, VERSION, ADV_TWOP_DEF_ADV_ON_PORT,
          ADV_TWOP_DEF_INTERVAL, "",
          false);                         // false = load balancer cronometra la respuesta
    setAdvisor ( this );
  } 

  //--------
  // ADV_AdvisorInitialize 

  public void ADV_AdvisorInitialize() {
    return; } 

  //--------
  // rutinas de acceso PUT y GET sincronizadas para las tablas hash

  synchronized ADV_nte getNte(Hashtable ht, String sName, String sHashKey) {
    ADV_nte nte = (ADV_nte)(ht.get(sHashKey));
    if (null != nte) {
      nte = (ADV_nte)nte.clone();
    }
    return nte;
  }
 synchronized void putNte(Hashtable ht, String sName, String sHashKey,
                          ADV_nte nte) { ht.put(sHashKey,nte); return;
} 


  //--------
  // getLoadHTTP - determinar la carga HTTP basándose en la respuesta del servidor 

  int getLoadHTTP(int iConnectTime, ADV_Thread caller) {
    int iLoad = ADV_HOST_INACCESSIBLE;
    int iRc = caller.send(ADV_HTTP_REQUEST_STRING);   // enviar mensaje de petición
                                                    // al servidor
    if (0 <= iRc) {                                 // ¿ha devuelto una anomalía la petición? 
      StringBuffer sbReceiveData = new StringBuffer("") // asignar un almacenamiento intermedio
                                                        // para la respuesta
      iRc = caller.receive(sbReceiveData);              // obtener la respuesta del servidor

      if (0 <= iRc) {                             // ¿ha devuelto una anomalía la recepción? 
        if (0 < sbReceiveData.length()) {         // ¿hay datos ahí? 
          iLoad = SUCCESS;                        // ignorar los datos recuperados y
                                                  // devolver un código de operación satisfactoria
      }
    }
  }
  return iLoad;
} 


//--------
// getLoadSSL() - determinar la carga SSL basándose en la respuesta del servidor 

int getLoadSSL(int iConnectTime, ASV_Thread caller) {
  int iLoad = ADV_HOST_INACCESSIBLE;
  int iRc; 

  CMNByteArrayWrapper cbawClientHello = new CMNByteArrayWrapper(
                                                  abClientHello);
  Socket socket = caller.getSocket();

  try {
      socket.getOutputStream().write(abClientHello); // Llevar a cabo una recepción. 
      socket.getInputStream().read();                // Si la recepción ha sido correcta,
                                                     // devolver una carga de 0. No nos
                                                     // ocupamos del contenido de los datos y
                                                     // la hebra ADV_Thread calcula
                                                     // la carga. 
      iLoad = 0;
  } catch (IOException e) {           // Si hubiera un error, iLoad lo incluiría como valor predeterminado. 
  }
  return iLoad;
} 


//--------
// getLoad - resultados de la fusión de los métodos HTTP y SSL 

public int getLoad(int iConnectTime, ADV_Thread caller) {
  int iLoadHTTP;
  int iLoadSSL;
  int iLoad;
  int iRc;

  String sCluster = caller.getCurrentClusterId();  // dirección de clúster actual
  int iPort = getAdviseOnPort();
  String sServer = caller.getCurrentServerId();
  String sHashKey = sCluster = ":" + sServer;      // clave de tabla hash 

  if (ADV_TWOP_PORT_HTTP == iPort) {                // gestionar un servidor HTTP
    iLoadHTTP = getLoadHTTP(iConnectTime, caller);  // obtener la carga de HTTP

    ADV_nte nteHTTP = newADV_nte(sCluster, iPort, sServer, iLoadHTTP);
    putNte(htTwopHTTP, "HTTP", sHashKey, nteHTTP);     // guardar la información
                                                       // de la carga HTTP
    ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey);  // obtener la información
                                                          // de SSL
      if (null != nteSSL) {
        if (true == nteSSL.isCurrent(this)) {              // comprobar la indicación de fecha y hora
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // ¿funciona
                                                                   // SSL? 
            iLoad = iLoadHTTP;
          } else {                      // SSL no funciona, por lo tanto marcar el servidor HTTP como inactivo
            iLoad= ADV_HOST_INACCESSIBLE;
          }
        } else {                 // la información de SSL ha caducado, por lo tanto marcar
                                 // el servidor HTTP como inactivo
          iLoad = ADV_HOST_INACCESSIBLE;
       }
     } else {                   // no hay información de carga sobre SSL, informar
                                // getLoadHTTP() results
       iLoad = iLoadHTTP;
     }
   }
   else if (ADV_TWOP_PORT_SSL == iPort) {             // gestionar un servidor SSL
     iLoadSSL = getLoadSSL(iConnectTime, caller);     // obtener la carga de SSL

     ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL);
     putNte(htTwopSSL, "SSL", sHashKey, nteSSL);      // guardar la info. de carga de SSL. 

     ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey);   // obtener la
                                                              // información  de HTTP
     if (null != nteHTTP) {
       if (true == nteHTTP.isCurrent(this)) {                 // comprobar la indicación de fecha y hora
         if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) {   // ¿funciona
                                                                  // HTTP? 
           iLoad = iLoadSSL;
         } else {             // el servidor HTTP no funciona, por lo tanto marcar SSL como inactivo
           iLoad = ADV_HOST_INACCESSIBLE;
         }
       } else {     // información de HTTP caducada, por lo tanto marcar SSL como inactivo
         iLoad = ADV_HOST_INACCESSIBLE;
       }
     } else {                 // no hay información de carga sobre HTTP, informar
                              // resultados de getLoadSSL()
       iLoad = iLoadSSL;
     }
   } 

 //--------
 // manejador de errores 

   else {
     iLoad = ADV_HOST_INACCESSIBLE;
   }
   return iLoad;
  }
} 



Referencia relacionada
Ejemplo: asesor de ejemplo
Tema de referencia    

Condiciones de uso | Comentarios

Última actualización: 31 de julio de 2008, 3:18:06 PM EDT
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.edge.doc/lb/info/ae/rprf_advex2port.html