WebSphere Load Balancer for IPv4 and IPv6
             Betriebssysteme: AIX, HP-UX, Linux, Solaris, Windows

             Inhaltsverzeichnis und Suchergebnisse personalisieren

Beispiel: Advisor-Funktion mit zwei Ports implementieren

Das folgende Beispiel zeigt, wie eine Advisor-Funktion mit zwei Ports implementiert wird. Dieses Beispiel für eine angepasste Advisor-Funktion veranschaulicht, wie Fehler für einen Port eines Servers basierend auf dem eigenen Status und dem Status eines anderen Serverdämons, der an einem anderen Port auf derselben Servermaschine ausgeführt wird, erkannt werden können.

Wenn der HTTP-Dämon an Port 80 beispielsweise nicht mehr reagiert, möchten Sie möglicherweise auch keinen Datenverkehr mehr an den SSL-Dämon an Port 443 weiterleiten.

Dieser Advisor ist aggressiver als Standard-Advisor, weil er jeden Server, der keine Antwort sendet, als funktionsunfähig betrachtet und deshalb als inaktiv markiert. Standard-Advisor-Funktionen stufen nicht reagierende Server als sehr langsam ein. Diese Advisor-Funktion markiert einen Server für den HTTP-Port und den SSL-Port als inaktiv, wenn einer der Ports keine Antwort liefert.

Zur Verwendung dieser angepassten Advisor-Funktion startet der Administrator zwei Instanzen des Advisors: eine für den HTTP-Port und eine für den SSL-Port. Die Advisor-Funktion instanziert zwei statische globale Hash-Tabellen, eine für HTTP und eine für SSL. Jede Advisor-Funktion versucht, mit ihrem Serverdämon zu kommunizieren, und speichert die Ergebnisse dieses Ereignisses in seiner Hash-Tabelle. Der Wert, den jede Advisor-Funktion an die Basis-Advisor-Klasse zurückgibt, hängt von der Fähigkeit der Advisor-Funktion zur Kommunikation mit seinem eigenen Serverdämon und der Fähigkeit der Partner-Advisor-Funktion zur Kommunikation mit deren Dämon ab.

Die folgenden angepassten Methoden werden verwendet.
Die folgenden Fehlerbedingungen werden erkannt:
Das folgende Beispiel verknüpft Port 80 mit HTTP und Port 443 mit SSL, kann aber angepasst werden, um eine beliebige Portkombination festzulegen:
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; 

//--------
// Tabellenelement für die in dieser angepassten Advisor-Funktion verwendeten Hash-Tabellen definieren

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

//--------
// Konstruktor

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

//--------
// Prüfen, ob dieses Element aktuell oder verfallen ist
  public boolean isCurrent(ADV_twop oThis) {
    boolean bCurrent;
    int iLifetimeMs = 3 * 1000 * oThis.getInterval();     // 3 Advisor-Zyklen als
                                                          // Lebensdauer festlegen
    Date dNow = new Date();
    Date dExpires = new Date(dTimestamp.getTime() + iLifetimeMs);

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

//--------
// Zugriffsmechanismen für Werte

 public int getLoadValue() { return iLoad; } 

//--------
// Klonen (Beschädigung zwischen Threads vermeiden)

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

} 

//--------
// Angepasste Advisor-Funktion definieren

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; 

   //--------
   // Tabellen für portspezifische Protokollinformationen definieren

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

   //--------
   // Bytefeldgruppe mit einer Hello-Nachricht des SSL-Clients erstellen

   public static final byte[] abClientHello = {
     (byte)0x80, (byte)0x1c,
     (byte)0x01,                                // Client-Hello
     (byte)0x03, (byte)0x00,                    // SSL-Version
     (byte)0x00, (byte)0x03,                    // Länge der Verschlüsselungsspezifikation (Bytes)
     (byte)0x00, (byte)0x00,                    // Länge der Sitzungs-ID (Bytes)
     (byte)0x00, (byte)0x10,                    // Länge der Anforderungsdaten (Bytes)
     (byte)0x00, (byte)0x00, (byte)0x03,        // Verschlüsselungsspezifikation
     (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20,    // Anforderungsdaten
     (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 }; 

  //--------
  // Konstruktor

  public ADV_twop() {
    super(ADV_TWOP_NAME, VERSION, ADV_TWOP_DEF_ADV_ON_PORT,
          ADV_TWOP_DEF_INTERVAL, "",
          false);                         // false = Load Balancer regelt die Antwort
    setAdvisor ( this );
  }

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

  public void ADV_AdvisorInitialize() { 
    return; } 

  //--------
  // Synchronisierte PUT- und GET-Zugriffsroutinen für die Hash-Tabellen

  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 - HTTP-Last auf der Basis der Serverantwort bestimmen

  int getLoadHTTP(int iConnectTime, ADV_Thread caller) {
    int iLoad = ADV_HOST_INACCESSIBLE;
    int iRc = caller.send(ADV_HTTP_REQUEST_STRING);   // Anforderungsnachricht an
                                                    // den Server senden
    if (0 <= iRc) {                                 // Hat die Anforderung einen Fehler zurückgegeben?
      StringBuffer sbReceiveData = new StringBuffer("") // Puffer für die Antwort
                                                        // zuordnen
      iRc = caller.receive(sbReceiveData);              // Antwort vom Server abrufen

      if (0 <= iRc) {                             // Hat receive einen Fehler zurückgegeben?
        if (0 < sbReceiveData.length()) {         // Sind Daten vorhanden? 
          iLoad = SUCCESS;                        // Abgerufene Daten ignorieren und
                                                  // Erfolgscode zurückgeben
      }
    }
  }
  return iLoad;
}


//--------
// getLoadSSL() - SSL-Last auf der Basis der Serverantwort bestimmen

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); // receive (Empfang) durchführen. 
      socket.getInputStream().read();                // Bei erfolgreichem Empfang
                                                     // 0 als Lastwert zurückgeben. Der
                                                     // Dateninhalt spielt keine Rolle,
                                                     // und die Last wird vom
                                                     // ADV_Thread-Thread berechnet.
      iLoad = 0;
  } catch (IOException e) {           // Bei einem Fehler als Standardwert für iLoad verwenden.
  } 
  return iLoad; 
} 


//--------
// getLoad - Ergebnisse der HTTP- und SSL-Methoden zusammenführen

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

  String sCluster = caller.getCurrentClusterId();  // aktuelle Clusteradresse
  int iPort = getAdviseOnPort();
  String sServer = caller.getCurrentServerId();
  String sHashKey = sCluster = ":" + sServer;      // Schlüssel für Hash-Tabelle

  if (ADV_TWOP_PORT_HTTP == iPort) {                // HTTP-Server bearbeiten
    iLoadHTTP = getLoadHTTP(iConnectTime, caller);  // Last für HTTP abrufen

    ADV_nte nteHTTP = newADV_nte(sCluster, iPort, sServer, iLoadHTTP);
    putNte(htTwopHTTP, "HTTP", sHashKey, nteHTTP);     // HTTP-Lastinformationen
                                                       // speichern
    ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey);  // SSL-Informationen
                                                          // abrufen
      if (null != nteSSL) {
        if (true == nteSSL.isCurrent(this)) {              // Zeitmarke prüfen
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // Funktioniert
                                                                   // SSL?
            iLoad = iLoadHTTP;
          } else {                      // SSL funktioniert nicht, deshalb HTTP-Server als inaktiv markieren
            iLoad= ADV_HOST_INACCESSIBLE;
          }
        } else {                 // SSL-Informationen sind verfallen, deshalb
                                 // HTTP-Server als inaktiv markieren
          iLoad = ADV_HOST_INACCESSIBLE;
       }
     } else {                   // Keine Lastinformationen zu SSL,
                                // Ergebnisse von getLoadHTTP() melden
       iLoad = iLoadHTTP;
     }
   }
   else if (ADV_TWOP_PORT_SSL == iPort) {             // SSL-Server bearbeiten
     iLoadSSL = getLoadSSL(iConnectTime, caller);     // Last für SSL abrufen

     ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL);
     putNte(htTwopSSL, "SSL", sHashKey, nteSSL);      // SSL-Lastinformationen speichern

     ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey);   // HTTP-Informationen
                                                              // abrufen
     if (null != nteHTTP) {
       if (true == nteHTTP.isCurrent(this)) {                 // Zeitmarke prüfen
         if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) {   // Funktioniert
                                                                  // HTTP?
           iLoad = iLoadSSL;
         } else {             // HTTP-Server funktioniert nicht, dedshalb SSL als inaktiv markieren
           iLoad = ADV_HOST_INACCESSIBLE;
         }
       } else {     // Verfallene Informationen von HTTP, deshalb SSL als inaktiv markieren
         iLoad = ADV_HOST_INACCESSIBLE;
       }
     } else {                 // Keine Lastinformationen für HTTP,
                              // Ergebnisse von getLoadSSL() melden
       iLoad = iLoadSSL;
     }
   }

 //--------
 // Fehlerbehandlungsroutine

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



Zugehörige Referenzen
Beispiel: Beispiel-Advisor-Funktion
Referenz    

Nutzungsbedingungen | Feedback

Letzte Aktualisierung: 31. Juli 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