[AIX HP-UX Linux Solaris Windows]

Beispiel: Advisor mit zwei Ports implementieren

Das folgende Beispiel zeigt, wie ein Advisor mit zwei Ports implementiert wird. Dieses Beispiel für einen angepassten Advisor 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 Standardadvisors, weil er jeden Server, der keine Antwort sendet, als funktionsunfähig betrachtet und deshalb als inaktiv markiert. Standardadvisor stufen nicht reagierende Server als sehr langsam ein. Dieser Advisor markiert einen Server für den HTTP-Port und den SSL-Port als inaktiv, wenn einer der Ports keine Antwort liefert.

Zur Verwendung dieses angepassten Advisors startet der Administrator zwei Instanzen des Advisors: eine für den HTTP-Port und eine für den SSL-Port. Der Advisor instanziiert zwei statische globale Hashtabellen, eine für HTTP und eine für SSL. Jeder Advisor versucht, mit ihrem Serverdämon zu kommunizieren, und speichert die Ergebnisse dieses Ereignisses in seiner Hashtabelle. Der Wert, den jeder Advisor an die Basisadvisorklasse zurückgibt, ist abhängig von der Fähigkeit des Advisors zur Kommunikation mit seinem eigenen Serverdämon und der Fähigkeit des Partneradvisors zur Kommunikation mit dessen Dämon.

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 diesem angepassten Advisor verwendeten Hashtabellen 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 abgelaufen ist
    public boolean isCurrent(ADV_twop oThis) {
        boolean bCurrent;
        int iLifetimeMs = 3 * 1000 * oThis.getInterval();   // 3 Advisorzyklen 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;
    } 
  } 

} 

//-------- 
// Angepassten Advisor 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 (Byte)
         (byte)0x00, (byte)0x00,   // Länge der Sitzungs-ID (Byte)
         (byte)0x00, (byte)0x10,   // Länge der Anforderungsdaten (Byte)
         (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 terminiert die Antwort
        setAdvisor ( this );
  } 

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

    public void ADV_AdvisorInitialize() {
    return; } 

  //-------- 
    // Synchronisierte PUT- und GET-Zugriffsroutinen für die Hashtabellen
  
    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
                                                     // 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 Hashtabelle

      if (ADV_TWOP_PORT_HTTP == iPort) {              // HTTP-Server ausführen
          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 abgelaufen, 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 ausführen
           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 funktioniert nicht, deshalb SSL als inaktiv markieren
                 iLoad = ADV_HOST_INACCESSIBLE;
         } 
               } else {     // Abgelaufene Informationen von HTTP, deshalb SSL als inaktiv markieren
               iLoad = ADV_HOST_INACCESSIBLE;
       } 
           } else {        // Keine Lastinformationen zu HTTP,
                      // Ergebnisse von getLoadSSL() melden
               iLoad = iLoadSSL;
     } 
   } 

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

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



Zugehörige Verweise
Beispiel: Beispieladvisor
Referenzartikel Referenzartikel    

Nutzungsbedingungen | Feedback

last-updated-altLetzte Aktualisierung: Jul 5, 2011 11:00:34 AM EDT
Dateiname: rprf_advex2port.html