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, in caso di mancata risposta da entrambe le porte.

Per utilizzare questo advisor personalizzato, l'amministratore avvia due istanze dell'advisor: una sulla porta HTTP e una sulla porta SSL. L'advisor crea le istanze di due tabelle hash globali statiche, una per HTTP e una per SSL. Ciascun advisor tenta di comunicare con il relativo daemon server e memorizza i risultati di questo evento nella tabella hash correlata. 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 è attivo 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; 
  } 

//-------- 
// accessori del valore 

 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 contengono le informazioni cronologiche specifiche 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,                    // lungh dati challenge (byte) 
     (byte)0x00, (byte)0x00, (byte)0x03,        // spec cifra
     (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20,    // dati challenge
     (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 programma la 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 messaggio richiesta 
                                                    // al server 
    if (0 <= iRc) {           // la richiesta restituisce un errore? 
      StringBuffer sbReceiveData = new StringBuffer("")    // allocare un buffer 
                                                        // for the response 
      iRc = caller.receive(sbReceiveData);    // ricevere la risposta dal server 
      
      if (0 <= iRc) {           // la richiesta restituisce un errore? 
        if (0 < sbReceiveData.length()) {      // sono presenti dati? 
          iLoad = SUCCESS;                        // ignorare i dati richiamati e 
                                                  // restituire il 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); // Effettua 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 ad un errore, iLoad utilizzerà il valore predefinito. 
  } 
  return iLoad; 
} 


//-------- 
// getLoad - unire i risultati ottenuti 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 
                                                       // informazioni HTTP 
    ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey);  // ricevere 
                                                          // informazioni HTTP
      if (null != nteSSL) { 
        if (true == nteSSL.isCurrent(this)) {              // verificare l'ora 
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // SSL 
                                                                   // è in esecuzione? 
            iLoad = iLoadHTTP; 
          } else {                      // SSL non in esecuzione, il server HTTP è indicato come inattivo 
            iLoad= ADV_HOST_INACCESSIBLE; 
          } 
        } else {                 // informazioni SSL scadute, contrassegnare il 
                                 // server HTTP come inattivo 
          iLoad = ADV_HOST_INACCESSIBLE; 
       } 
     } else {                   // nessuna informazione sul carico per SSL, riportare 
                                // i risultati di 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 informazioni sul carico SSL. 

     ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey);   // ricevere 
                                                              // informazioni HTTP 
     if (null != nteHTTP) { 
       if (true == nteHTTP.isCurrent(this)) {       // verificare la data/ora 
         if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) {  // HTTP è 
                                                                  // è in esecuzione? 
           iLoad = iLoadSSL; 
         } else {             // il server HTTP non funziona, contrassegnare SSL come inattivo 
           iLoad = ADV_HOST_INACCESSIBLE; 
         } 
       } else {     // informazioni scadute da HTTP, contrassegnare SSL come inattivo 
         iLoad = ADV_HOST_INACCESSIBLE; 
       } 
     } else {                 // nessuna informazione sul carico per HTTP, riportare 
                              // i risultati di getLoadSSL() 
       iLoad = iLoadSSL; 
     } 
   } 

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

   else { 
     iLoad = ADV_HOST_INACCESSIBLE; 
   } 
   return iLoad; 
  } 
} 
Argomento di riferimento    

Clausole e condizioni per i centri informazioni | Feedback

Ultimo aggiornamento: May 14, 2012 01:50 PM EDT
Nome file: rprf_advex2port.html