[AIX HP-UX Linux Solaris Windows]

例: 2 ポート advisor の実装

次の例では、2 ポート advisor を実装する方法を示します。 このカスタム advisor のサンプルでは、サーバーのいずれか 1 つのポートで発生した障害を検出する機能を具体的に示しています。この検出は、そのポート自体の状況、および、同一サーバー・マシン上に あるもう 1 つのポート上で実行されている別のサーバー・デーモンの状況の両方に基づいて行われます。

例えば、ポート 80 上の HTTP デーモンが応答を停止した場合は、 ポート 443 上で実行されている SSL デーモンへのトラフィックのルーティング停止も 必要になることが考えられます。

このカスタム advisor は、標準 advisor よりもアグレッシブです。それは、応答を送信しないすべてのサーバーを機能が停止したサーバーであると見なし、ダウンの マークを付けるからです。標準 advisor では、応答のないサーバーは、処理速度の非常に遅いサーバーと 見なします。このカスタム advisor では、HTTP ポートか SSL ポートのいずれか一方から応答がないと、両方のポートがダウンしているというマークを サーバーに付けます。

このカスタム advisor を使用する際、管理者は、この advisor の 2 つのインスタンス、すなわち、HTTP ポート上のインスタンスと SSL ポート上のインスタンスを 開始します。この advisor では、HTTP 用と SSL 用の 2 つの静的なグローバル・ハッシュ・テーブルを インスタンス化します。各 advisor では、そのサーバー・デーモンとの通信を試行し、ハッシュ・テーブル内に このイベントの結果を保管します。各 advisor が基本 advisor クラスに戻す値は、各 advisor が自身のサーバー・デーモンと通信する機能と、 パートナー advisor が自身のデーモンと通信する機能との両方によって決まります。

使用されるカスタム・メソッドは次のとおりです。
検出されるエラー条件は次のとおりです。
このサンプルは HTTP 用のポート 80 と SSL 用のポート 443 をリンクするように作成されていますが、ポートの組み合わせは任意に調整できます。
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;

//-------- 
// このカスタム 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(); 
  } 

//-------- 
// このエレメントは現在有効か、有効期限が切れているかを検査します。
  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; } 


//-------- 
// 複製 (スレッド間の破損を回避)

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

} 

//-------- 
// カスタム 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.0rnAccept: */*rnUser-Agent: " +
    "IBM_LB_Custom_Advisor\r\n\r\n";
   //-------- 
   // SSL client hello メッセージを使用してバイト配列を作成します

   public static final byte[] abClientHello = { 
     (byte)0x80, (byte)0x1c, 
     (byte)0x01,                                // client hello
     (byte)0x03, (byte)0x00,                    // SSL バージョン
     (byte)0x00, (byte)0x03,                    // cipher spec len (バイト)
     (byte)0x00, (byte)0x00,                    // session ID len (バイト)
     (byte)0x00, (byte)0x10,                    // challenge data len (バイト)
     (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 および GET アクセス・ルーチン
  
  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 の負荷を特定します

    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()) {         // データがあるか           
          iLoad = SUCCESS;                        // 受信データを無視し、
                                                  // 成功コードを返します
      } 
    } 
  } 
  return iLoad; 
} 


//-------- 
// getLoadSSL() - サーバーの応答に基づいて SSL の負荷を特定します

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();                // 受信が成功した場合、
                                                     // 負荷 0 を返します。データの
                                                     // 内容は関係なく、
                                                     // ADV_Thread スレッドが
                                                     // 負荷を計算します。       iLoad = 0; 
  } catch (IOException e) {           // エラー時、iLoad はデフォルトでこれに設定されます。
  } 
  return iLoad; 
} 


//-------- 
// getLoad - HTTP メソッドと SSL メソッドの結果をマージします

public int getLoad(int iConnectTime, ADV_Thread caller) { 
  int iLoadHTTP; 
  int iLoadSSL; 
  int iLoad; 
  int iRc; 
  
  String sCluster = caller.getCurrentClusterId();  // 現行クラスター・アドレス
  int iPort = getAdviseOnPort(); 
  String sServer = caller.getCurrentServerId(); 
  String sHashKey = sCluster = ":" + sServer;      // ハッシュ・テーブル・キー

  if (ADV_TWOP_PORT_HTTP == iPort) {                // HTTP サーバーを処理します
    iLoadHTTP = getLoadHTTP(iConnectTime, caller);  // 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)) {              // タイム・スタンプを確認します
          if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) {    // is SSL 
                                                                                                                                      // working?
iLoad = iLoadHTTP; 
          } else {                      // SSL が機能していないため、HTTP サーバーにダウンのマークを付けます
            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) {             // SSL サーバーを処理します
     iLoadSSL = getLoadSSL(iConnectTime, caller);     // SSL の負荷を取得します
  
     ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL); 
     putNte(htTwopSSL, "SSL", sHashKey, nteSSL);      // SSL の負荷情報を保存します。

     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 サーバーが機能していないため、SSL にダウンのマークを付けます
           iLoad = ADV_HOST_INACCESSIBLE; 
         } 
       } else {     // HTTP からの情報の有効期限が切れているため、SSL にダウンのマークを付けます
         iLoad = ADV_HOST_INACCESSIBLE; 
       } 
           } else {       // no load information about HTTP, report 
                     // getLoadSSL() results
            iLoad = iLoadSSL; 
} 
   } 

 //-------- 
 // エラー・ハンドラー

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



関連資料
例: サンプル advisor
参照トピック 参照トピック    

ご利用条件 | フィードバック

最終更新最終更新: Jun 21, 2011 12:49:06 PM EDT
ファイル名: rprf_advex2port.html