WebSphere Load Balancer pour IPv4 et IPv6
Systèmes d'exploitation : AIX, HP-UX, Linux, Solaris, Windows

             Personnalisation de la table des matières et des résultats de la recherche

Exemple : Implémentation d'un conseiller à deux ports

L'exemple suivant montre comment implémenter un conseiller à deux ports. Cet exemple de conseiller personnalisé illustre la possibilité de détecter l'échec d'un port d'un serveur en fonction de son propre statut et du statut d'un autre démon de serveur exécuté sur un autre port du même serveur.

Par exemple, si le démon HTTP sur le port 80 ne répond plus, vous pouvez également arrêter l'acheminement du trafic vers le démon SSL sur le port 443.

Ce conseiller est plus agressif que les conseillers standard, car il prend en compte tout serveur qui n'envoie pas de réponse après s'être arrêté et le marque comme arrêté. Les conseillers standard considèrent les serveurs qui ne répondent pas comme des serveurs très lents. Ce conseiller marque un serveur comme arrêté pour les ports HTTP et SSL si l'un de ces ports ne répond pas.

Pour utiliser ce conseiller personnalisé, l'administrateur démarre deux instances du conseiller : une sur le port HTTP et l'autre sur le port SSL. Le conseiller instancie deux tables de hachage globales statiques : une pour HTTP et l'autre pour SSL. Chaque conseiller essaye de communiquer avec son démon serveur et stocke les résultats de cet événement dans sa table de hachage. La valeur renvoyée par chaque conseiller à la classe du conseiller de base dépend de la possibilité de communiquer avec son propre démon serveur et de la faculté du conseiller partenaire de communiquer avec son démon.

Les méthodes personnalisées suivantes sont utilisées.
Les conditions d'erreur suivantes sont détectées :
Cet exemple est créé pour associer les ports 80 pour HTTP et 443 pour SSL, mais il peut être personnalisé et accepte toute combinaison de ports.
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; 

//-------- 
// Define the table element for the hash tables used in this custom advisor 

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(); 
  } 

//-------- 
// check whether this element is current or expired 
  public boolean isCurrent(ADV_twop oThis) { 
    boolean bCurrent; 
    int iLifetimeMs = 3 * 1000 * oThis.getInterval();     // set lifetime as 
                                                          // 3 advisor cycles 
    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 (avoids corruption between threads) 

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

} 

//-------- 
// define the custom advisor

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; 

   //-------- 
   // define tables to hold port-specific history information 

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

   //-------- 
   // create byte array with SSL client hello message 

   public static final byte[] abClientHello = { 
     (byte)0x80, (byte)0x1c, 
     (byte)0x01,                                // client hello 
     (byte)0x03, (byte)0x00,                    // SSL version 
     (byte)0x00, (byte)0x03,                    // cipher spec len (bytes) 
     (byte)0x00, (byte)0x00,                    // session ID len (bytes) 
     (byte)0x00, (byte)0x10,                    // challenge data len (bytes) 
     (byte)0x00, (byte)0x00, (byte)0x03,        // cipher spec
     (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20,    // challenge data
     (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 times the response 
    setAdvisor ( this ); 
  } 

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

  public void ADV_AdvisorInitialize() { 
    return; } 

  //-------- 
  // synchronized PUT and GET access routines for the hash tables 
  
  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 - determine HTTP load based on server response 

  int getLoadHTTP(int iConnectTime, ADV_Thread caller) { 
    int iLoad = ADV_HOST_INACCESSIBLE; 
    int iRc = caller.send(ADV_HTTP_REQUEST_STRING);   // send request message 
                                                    // to server 
    if (0 <= iRc) {                                 // did the request return a failure? 
      StringBuffer sbReceiveData = new StringBuffer("") // allocate a buffer 
                                                        // for the response 
      iRc = caller.receive(sbReceiveData);              // get response from server 
      
      if (0 <= iRc) {                             // did the receive return a failure? 
        if (0 < sbReceiveData.length()) {         // is data there? 
          iLoad = SUCCESS;                        // ignore retrieved data and 
                                                  // return success code 
      } 
    } 
  } 
  return iLoad; 
} 


//-------- 
// getLoadSSL() - determine SSL load based on server response 

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); // Perform a receive. 
      socket.getInputStream().read();                // If receive is successful,
                                                     // return load of 0. We are not
                                                     // concerned with data's contents,
                                                     // and the load is calculated by 
                                                     // the ADV_Thread thread. 
      iLoad = 0; 
  } catch (IOException e) {           // Upon error, iLoad will default to it. 
  } 
  return iLoad; 
} 


//-------- 
// getLoad - merge results from the HTTP and SSL methods 

public int getLoad(int iConnectTime, ADV_Thread caller) { 
  int iLoadHTTP; 
  int iLoadSSL; 
  int iLoad; 
  int iRc; 
  
  String sCluster = caller.getCurrentClusterId();  // current cluster address 
  int iPort = getAdviseOnPort(); 
  String sServer = caller.getCurrentServerId(); 
  String sHashKey = sCluster = ":" + sServer;      // hash table key 

  if (ADV_TWOP_PORT_HTTP == iPort) {                // handle an HTTP server 
    iLoadHTTP = getLoadHTTP(iConnectTime, caller);  // get the load for HTTP 
    
    ADV_nte nteHTTP = newADV_nte(sCluster, iPort, sServer, iLoadHTTP); 
    putNte(htTwopHTTP, "HTTP", sHashKey, nteHTTP);     // save HTTP load 
                                                       // information 
    ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey);  // get SSL 
                                                          // information
      if (null != nteSSL) { 
        if (true == nteSSL.isCurrent(this)) {              // check the time stamp 
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // is SSL 
                                                                   // working? 
            iLoad = iLoadHTTP; 
          } else {                      // SSL is not working, so mark the HTTP server down 
            iLoad= ADV_HOST_INACCESSIBLE; 
          } 
        } else {                 // SSL information is expired, so mark the 
                                 // HTTP server down 
          iLoad = ADV_HOST_INACCESSIBLE; 
       } 
     } else {                   // no load information about SSL, report 
                                // getLoadHTTP() results 
       iLoad = iLoadHTTP; 
     } 
   } 
   else if (ADV_TWOP_PORT_SSL == iPort) {             // handle an SSL server 
     iLoadSSL = getLoadSSL(iConnectTime, caller);     // get load for SSL 
  
     ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL); 
     putNte(htTwopSSL, "SSL", sHashKey, nteSSL);      // save SSL load info. 

     ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey);   // get HTTP 
                                                              // information 
     if (null != nteHTTP) { 
       if (true == nteHTTP.isCurrent(this)) {                 // check the timestamp 
         if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) {   // is HTTP 
                                                                  // working? 
           iLoad = iLoadSSL; 
         } else {             // HTTP server is not working, so mark SSL down 
           iLoad = ADV_HOST_INACCESSIBLE; 
         } 
       } else {     // expired information from HTTP, so mark SSL down 
         iLoad = ADV_HOST_INACCESSIBLE; 
       } 
     } else {                 // no load information about HTTP, report 
                              // getLoadSSL() results 
       iLoad = iLoadSSL; 
     } 
   } 

 //-------- 
 // error handler 

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



Référence associée
Exemple : Exemple de conseiller
Rubrique de référence    

Conditions d'utilisation | Commentaires

Dernière mise à jour : 31 juillet 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