Nginx がポーリング アルゴリズムを実装する方法

WBOY
リリース: 2023-05-21 21:43:13
転載
1545 人が閲覧しました

単純なポーリング アルゴリズム

このアルゴリズムは比較的単純です。たとえば、3 つのサーバーがあるとします。

最初のサーバー 192.168.1.1
2 番目のサーバー 192.168.1.2
3 番目のサーバーサーバー 192.168.1.3

最初のリクエストが到着すると、デフォルトで最初のサーバーにアクセスし、2 番目のリクエストは 2 番目のサーバーにアクセスし、3 番目のサーバーにアクセスします。は 3 番目のステーションにアクセスし、4 番目のリクエストは最初のステーションにアクセスする、というようになります。以下は私のコードで実装された簡単なアルゴリズムです:

public class simplepolling {

  /**
   * key是ip
   */
  public static list <string> ipservice = new linkedlist <>();
  static {
    ipservice.add("192.168.1.1");
    ipservice.add("192.168.1.2");
    ipservice.add("192.168.1.3");
  }
  public static int pos = 0;
  public static string getip(){
    if(pos >= ipservice.size()){
      //防止索引越界
      pos = 0;
    }
    string ip = ipservice.get(pos);
    pos ++;
    return ip;

  }

  public static void main(string[] args) {
    for (int i = 0; i < 4; i++) {
      system.out.println(getip());

    }
  }
}
ログイン後にコピー

4 回のシミュレート実行の結果は

Nginx がポーリング アルゴリズムを実装する方法

サーバーのパフォーマンスがある場合現時点での比較は OK (192.168.1.1 など)、このサーバーでより多くのリクエストを処理できるようにしたいです。このとき、重み確率が関係します。このアルゴリズムは実装できません。後で説明するポーリング アップグレード アルゴリズムを参照してください。

加重ポーリング アルゴリズム

現時点では、目の前にある 3 台のサーバーの重みを設定する必要があります。たとえば、最初のサーバーは 5 に設定します。 、2 番目の設定は 1 に設定され、最初の設定は 1 に設定されます。 3 つの設定 1

##3 番目のサーバー192.168.1.31
最初のサーバー192.168.1.1 5
2 番目のサーバー192.168.1.21
現時点では、最初の 5 つのリクエストは最初のサーバーにアクセスし、6 番目のリクエストは 2 番目のサーバーにアクセスします。 、7 番目のリクエストは 3 番目のサーバーにアクセスします。

以下は私が指定したコード例です:

public class weightpolling {

  /**
   * key是ip,value是权重
   */
  public static map<string, integer> ipservice = new linkedhashmap<>();
  static {
    ipservice.put("192.168.1.1", 5);
    ipservice.put("192.168.1.2", 1);
    ipservice.put("192.168.1.3", 1);
  }
  public static int requestid = 0;
  public static int getandincrement() {
    return requestid++;
  }

  public static string getip(){
    //获取总的权重
    int totalweight =0;
    for (integer value : ipservice.values()) {
      totalweight+= value;
    }
    //获取当前轮询的值
    int andincrement = getandincrement();
    int pos = andincrement% totalweight;
    for (string ip : ipservice.keyset()) {
      if(pos < ipservice.get(ip)){
        return ip;
      }
      pos -= ipservice.get(ip);
    }
    return null;
  }

  public static void main(string[] args) {
    for (int i = 0; i < 7; i++) {
      system.out.println(getip());
    }
  }

}
ログイン後にコピー

現時点での実行結果は


Nginx がポーリング アルゴリズムを実装する方法

最初の結果です。最初のサーバーは 5 回実行され、次の 2 つのサーバーは 1 回実行されていることがわかります。もしかしたら、このアルゴリズムは悪くないと思うかもしれません。実は、このアルゴリズムの欠点は、最初のサーバーの重みが大きすぎると、最初のサーバーに対して多くのリクエストを実行する必要があり、この場合、分散が不均一になり、特定のサーバーに負荷がかかることです。サイズが大きすぎると崩壊につながります。この問題を解決するための 3 番目のアルゴリズムを後で紹介します。

Smooth Weighted Polling Algorithm

このアルゴリズムはより複雑になる可能性があり、最初に使用したときは少し混乱しました。見たのですが、よく分かりませんでした。後で関連する情報を読んで、自分の理解と組み合わせて、画像とテキストで説明しました。ここで例として挙げたサーバー構成と重みは、上記と同じです。

リクエスト 現在の体重 = 自重 選択後の現在の体重 総重量現在の最大体重返された ip選択後の現在の重量 = 現在の最大重量 - 総重量 #1{5, 1,1}75192.168.1.1{-2,1,1} ##234567上の図からわかるように、最初のサーバーの重みは 5 に設定されており、5 番目のリクエストではありません。以前は常に最初のサーバーで実行されていましたが、分散方式で実行されました。スケジューリング シーケンスは非常に均等であり、7 番目のリクエスト以降はスケジューリングが選択され、現在の重みが {0, 0, 0} に戻り、インスタンスの状態が初期状態と一致したため、今後スケジューリング操作を繰り返すことができます。
{3,2 ,2}73192.168.1.1{-4,2 ,2}
{1,3,3}73192.168 .1.2{1,-4 ,3}
{6,-3,4}7 6 192.168.1.1{-1,-3,4}
{4,-2,5}75192.168.1.3{4,-2,-2}
{9,-1,-1}79192.168.1.1 {2,-1,-1}
{7,0,0}77192.168.1.1{0,0,0}

前の図の意味をよく理解していない人もいるかもしれません。ここで簡単に説明します:

1. まず第一に、総重量は変わりません。デフォルトは現在のものです。重みを設定します。

2 の合計です。最初のリクエストが受信されると、デフォルトで現在の重みの選択値を {0,0,0} に初期化します。そのため、現在の重みの値は {5 0,1 になります。 0,1 0} ,5,1,1 は、目の前の各サーバーによって設定された重みです。

3. ここで、最初のリクエストの最大重みは 5 であると結論付けることができます。次に、最初のサーバー ip

4 に戻ります。選択後に現在の重みを設定します。これは、現在の最大重みから合計重み (5-7) を引いたものです。選択されていない重みの重みは変更されません。今回は現在の重みを取得します。重みの値 {5-7,1,1}

5 を選択します。2 番目のリクエストが来た場合は、上記の手順 2、3、4 を続けます。

まだある場合 理解できない場合は、Java コードを使用して実装したアルゴリズムを以下に示します:

public class polling {

  /**
   * key是ip,value是权重
   */
  public static map <string,integer> ipservice = new linkedhashmap <>();
  static {
    ipservice.put("192.168.1.1",5);
    ipservice.put("192.168.1.2",1);
    ipservice.put("192.168.1.3",1);
  }
  private static map<string,weight> weightmap = new linkedhashmap <>();

  public static string getip(){
    //计算总的权重
     int totalweight = 0;
    for (integer value : ipservice.values()) {
      totalweight+=value;
    }
    //首先判断weightmap是否为空
    if(weightmap.isempty()){
      ipservice.foreach((ip,weight)->{
        weight weights = new weight(ip, weight,0);
        weightmap.put(ip,weights);
      });
    }
    //给map中得对象设置当前权重
    weightmap.foreach((ip,weight)->{
      weight.setcurrentweight(weight.getweight() + weight.getcurrentweight());
    });

    //判断最大权重是否大于当前权重,如果为空或者小于当前权重,则把当前权重赋值给最大权重
    weight maxweight = null;
    for (weight weight : weightmap.values()) {
      if(maxweight ==null || weight.getcurrentweight() > maxweight.getcurrentweight()){
        maxweight = weight;
      }
    }
    //最后把当前最大权重减去总的权重
    maxweight.setcurrentweight(maxweight.getcurrentweight() - totalweight);
    //返回
    return maxweight.getip();
  }

  public static void main(string[] args) {
    //模拟轮询7次取ip
    for (int i = 0; i < 7; i++) {
      system.out.println(getip());
    }
  }

}

class weight{
  /**
   * ip
   */
  private string ip;
  /**
   * 设置得权重
   */
  private int weight;
  /**
   * 当前权重
   */
  private int currentweight;

  public weight(string ip, int weight,int currentweight) {
    this.ip = ip;
    this.weight = weight;
    this.currentweight = currentweight;
  }

  public string getip() {
    return ip;
  }

  public void setip(string ip) {
    this.ip = ip;
  }

  public int getweight() {
    return weight;
  }

  public void setweight(int weight) {
    this.weight = weight;
  }

  public int getcurrentweight() {
    return currentweight;
  }

  public void setcurrentweight(int currentweight) {
    this.currentweight = currentweight;
  }
}
ログイン後にコピー

コードの実行結果は次のとおりです:


#ここでの実行結果は、表で説明されているものと一致していることがわかります。 Nginx がポーリング アルゴリズムを実装する方法

以上がNginx がポーリング アルゴリズムを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!