WebSphere Load Balancer per IPv4 e IPv6
             Sistemi operativi: AIX, HP-UX, Linux, Solaris, Windows

             Personalizzazione dell'indice e dei risultati della ricerca

Esempio: Implementazione di un advisor a due porte

Il seguente esempio mostra come implementare un advisor a due porte. Questo esempio di advisor personalizzato dimostra la possibilità di rilevare un errore per una porta di un server in base al suo stato e allo stato di un daemon del server differente in esecuzione su un'altra porta sulla stessa macchina server.

Ad esempio, se il daemon HTTP sulla porta 80 smette di rispondere, potrebbe essere necessario arrestare l'instradamento del traffico al daemon SSL sulla porta 443.

Questo advisor è più aggressivo degli advisor standard, in quanto considera qualsiasi server che non invia una risposta come non funzionante e pertanto lo contrassegna come inattivo. Gli advisor standard considerano molto lenti i server che non rispondono. Questo advisor contrassegna un server come inattivo sia per la porta HTTP che per la porta SSL nel caso non vi sia una risposta dalla prima porta.

Per utilizzare questo advisor personalizzato, l'amministratore avvia due istanze dell'advisor: una sulla porta HTTP e una sulla porta SSL. L'advisor istanzia quindi due tabelle hash globali statiche, una per HTTP e una per SSL. Ogni advisor prova a comunicare con il daemon del server e memorizza i risultati di questo evento nella propria tabella hash. Il valore che ogni advisor restituisce alla classe dell'advisor di base dipende sia dalla capacità di comunicare con il proprio daemon del server che dalla capacità dell'advisor partner di comunicare con il relativo daemon.

Sono utilizzati i metodi personalizzati riportati di seguito.
Sono rilevate le seguenti condizioni di errore:
Questo esempio è scritto per collegare le porte 80 per HTTP e 443 per SSL, ma può essere adattato a qualsiasi combinazione di porte:
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; 

//--------
// Definire l'elemento di tabella per le tabelle hash utilizzate in questo advisor personalizzato 

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

//--------
// costruttore 

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

//--------
// verificare se questo elemento è corrente o scaduto
  public boolean isCurrent(ADV_twop oThis) {
    boolean bCurrent;
    int iLifetimeMs = 3 * 1000 * oThis.getInterval();     // impostare la durata come
                                                          // 3 cicli dell'advisor
    Date dNow = new Date();
    Date dExpires = new Date(dTimestamp.getTime() + iLifetimeMs); 

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

//-------- 
// value accessor(s) 

 public int getLoadValue() { return iLoad; } 

//--------
// clone (evita il danneggiamento tra thread) 

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

} 

//--------
// definire l'advisor personalizzato

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; 

   //--------
   // definire le tabelle che conterranno le informazioni sulla cronologia delle porte 

   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"; 

   //--------
   // creare un'array di byte con il messaggio hello del client SSL 

   public static final byte[] abClientHello = {
     (byte)0x80, (byte)0x1c,
     (byte)0x01,                                // hello client
     (byte)0x03, (byte)0x00,                    // versione SSL
     (byte)0x00, (byte)0x03,                    // lungh spec cifre (byte)
     (byte)0x00, (byte)0x00,                    // lungh ID sessione (byte)
     (byte)0x00, (byte)0x10,                    // lunghezza dati (byte)
     (byte)0x00, (byte)0x00, (byte)0x03,        // spec cifra
     (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20,    // dati
     (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 }; 

  //--------
// costruttore 

  public ADV_twop() {
    super(ADV_TWOP_NAME, VERSION, ADV_TWOP_DEF_ADV_ON_PORT,
          ADV_TWOP_DEF_INTERVAL, "",
          false);                         // false = load balancer imposta l'ora della risposta
    setAdvisor ( this );
  } 

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

  public void ADV_AdvisorInitialize() { 
    return; } 

  //--------
  // routine di accesso PUT e GET sincronizzate per le tabelle 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 - determinare il carico HTTP in base alla risposta del server 

  int getLoadHTTP(int iConnectTime, ADV_Thread caller) {
    int iLoad = ADV_HOST_INACCESSIBLE;
    int iRc = caller.send(ADV_HTTP_REQUEST_STRING);   // inviare il messaggio di richiesta
                                                    // al server
    if (0 <= iRc) {                                 // la richiesta ha restituito un errore? 
      StringBuffer sbReceiveData = new StringBuffer("") // assegnare un buffer
                                                        // per la risposta
      iRc = caller.receive(sbReceiveData);              // richiamare la risposta dal server

      if (0 <= iRc) {                             // la ricezione ha ricevuto un errore? 
        if (0 < sbReceiveData.length()) {         // i dati sono presenti? 
          iLoad = SUCCESS;                        // ignorare i dati richiamati e
                                                  // restituire un codice di riuscita
      }
    }
  }
  return iLoad;
} 


//--------
// getLoadSSL() - determinare il carico SSL in base alla risposta del server 

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); // Effettuare una ricezione. 
      socket.getInputStream().read();                // Se la ricezione riesce,
                                                     // viene restituito un carico pari 0. Non                                                     // si conosce il contenuto dei dati,
                                                     // e il carico viene calcolato mediante
                                                     // il thread ADV_Thread. 
      iLoad = 0;
  } catch (IOException e) {           // In seguito a un errore, iLoad utilizzerà il valore predefinito. 
  } 
  return iLoad; 
} 


//--------
// getLoad - unire i risultati dai metodi HTTP e SSL 

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

  String sCluster = caller.getCurrentClusterId();  // indirizzo cluster corrente
  int iPort = getAdviseOnPort();
  String sServer = caller.getCurrentServerId();
  String sHashKey = sCluster = ":" + sServer;      // chiave tabella hash 

  if (ADV_TWOP_PORT_HTTP == iPort) {                // gestire un server HTTP
    iLoadHTTP = getLoadHTTP(iConnectTime, caller);  // richiamare il carico per HTTP

    ADV_nte nteHTTP = newADV_nte(sCluster, iPort, sServer, iLoadHTTP);
    putNte(htTwopHTTP, "HTTP", sHashKey, nteHTTP);     // salvare le informazioni
                                                       // sul carico HTTP
    ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey);  // richiamare le informazioni
                                                          // SSL
      if (null != nteSSL) {
        if (true == nteSSL.isCurrent(this)) {              // verificare il formato orario
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // SSL
                                                                   // funziona? 
            iLoad = iLoadHTTP;
          } else {                      // SSL non funziona, quindi il server HTTP viene                                         // contrassegnato come inattivo
iLoad= ADV_HOST_INACCESSIBLE;
          }
        } else {                 // le informazioni SSL sono scadute, pertanto il server
                                 // HTTP viene contrassegnato come inattivo
          iLoad = ADV_HOST_INACCESSIBLE;
       }
     } else {                   // nessuna informazioni di carico su SSL, riportare
                                // i risultati getLoadHTTP()
       iLoad = iLoadHTTP;
     }
   }
   else if (ADV_TWOP_PORT_SSL == iPort) {             // gestire un server SSL
     iLoadSSL = getLoadSSL(iConnectTime, caller);     // richiamare il carico per SSL

     ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL);
     putNte(htTwopSSL, "SSL", sHashKey, nteSSL);      // salvare le info sul carico SSL. 

     ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey);   // richiamare le informazioni
                                                              // HTTP
     if (null != nteHTTP) {
       if (true == nteHTTP.isCurrent(this)) {                 // controllare il formato orario
         if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) {   // HTTP
                                                                  // funziona? 
           iLoad = iLoadSSL;
         } else {             // il server HTTP non funziona, quindi SSL viene contrassegnato                               // come inattivo
iLoad = ADV_HOST_INACCESSIBLE;
         }
       } else {     // informazioni scadute da HTTP, pertanto SSL viene contrassegnato come                     // inattivo
iLoad = ADV_HOST_INACCESSIBLE; }
     } else {                 // nessuna informazione di carico HTTP, riportare
                              // i risultati getLoadSSL()
       iLoad = iLoadSSL;
     }
   } 

 //--------
 // gestore errori 

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



Riferimento correlato
Esempio: advisor di esempio
Argomento di riferimento    

Termini di utilizzo | Feedback

Ultimo aggiornamento: 31 lug 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