Maison  >  Article  >  Opération et maintenance  >  Comment Nginx implémente l'algorithme d'interrogation

Comment Nginx implémente l'algorithme d'interrogation

WBOY
WBOYavant
2023-05-21 21:43:131546parcourir

Algorithme d'interrogation simple

Cet algorithme est relativement simple. Par exemple, vous avez trois serveurs

Le premier serveur 192.168.1.1
Le deuxième serveur 192.168.1.2.
Le troisième serveur 192.168.1.3

Après la première requête, il accédera au premier serveur par défaut, la deuxième requête viendra accéder au deuxième serveur et la troisième requête viendra accéder au troisième serveur . La quatrième demande vient visiter la première station, et ainsi de suite. Voici un algorithme simple implémenté par mon code :

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

    }
  }
}

Le résultat de 4 exécutions simulées est

Comment Nginx implémente lalgorithme dinterrogation

À l'heure actuelle, si j'ai un serveur avec de meilleures performances (comme 192.168.1.1), je veux ceci serveur pour traiter plus Une petite requête, cette fois implique la probabilité de poids, cet algorithme ne peut pas être implémenté, veuillez consulter l'algorithme de version améliorée d'interrogation que je décris plus tard.

Algorithme d'interrogation pondéré

À ce stade, je dois définir les poids des trois serveurs devant moi. Par exemple, le premier serveur est défini sur 5, le deuxième serveur est défini sur 1 et le troisième. le serveur est défini sur 1

Le premier serveur Serveur 192.168.1.1 5
Deuxième serveur 192.168.1.2 1
Troisième serveur 192.168.1.3 1

Top 5 en ce moment Chaque requête accédera au premier serveur, la sixième requête accédera au deuxième serveur et la septième requête accédera au troisième serveur.

Voici l'exemple de code que j'ai donné :

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

}

Le résultat en cours d'exécution à ce moment est

Comment Nginx implémente lalgorithme dinterrogation

Le premier serveur visible a été exécuté 5 fois, les 2 serveurs suivants ont été exécutés une fois, et bientôt. Peut-être pensez-vous que cet algorithme n'est pas mauvais. En fait, un inconvénient de cet algorithme est que si le poids du premier serveur est trop important, je devrai peut-être exécuter de nombreuses requêtes vers le premier serveur. Dans ce cas, la répartition est inégale et entraînera une pression sur un certain serveur. Une taille excessive conduit à l'effondrement. J'introduireai donc un troisième algorithme pour résoudre ce problème plus tard

Algorithme d'interrogation pondéré fluide

Cet algorithme est peut-être plus compliqué. Je ne l'ai pas compris la première fois que je l'ai vu plus tard. combiné avec, j'expliquerai ma propre compréhension avec des images et du texte. La configuration du serveur et le poids que je donne à titre d'exemple ici sont toujours les mêmes que ci-dessus

5192.1 68 .1.1497Comme vous pouvez le voir sur la photo ci-dessus, bien que le poids de le premier serveur est défini sur 5, ce n'est pas la cinquième requête. Elles sont toutes exécutées sur le premier serveur, mais sont exécutées de manière distribuée. La séquence de planification est très uniforme et le poids actuel revient à {0, 0, 0} après la sélection de la septième planification, l'état de l'instance est cohérent avec l'état initial, donc l'opération de planification peut être répétée à l'avenir. Certaines personnes peuvent ne pas comprendre clairement la signification de l'image précédente. Permettez-moi de la décrire brièvement ici : 1. Tout d'abord, le poids total ne changera pas. La valeur par défaut est la somme des poids actuellement définis 2. . Dans le premier cas, lorsqu'une demande arrive, j'initialise la valeur de poids actuelle sélectionnée par défaut à {0,0,0}, donc la valeur de poids actuelle est {5+0,1+0,1+0}, où 5. ,1,1 est le poids défini par chaque serveur que nous avons défini précédemment. 3. Ici, nous pouvons conclure que le poids maximum de la première demande est de 5. Revenons ensuite au premier serveur ip4. Ensuite, nous définissons le poids actuel après sélection. Voici le poids maximum actuel moins le poids total (5-7). Le poids du poids non sélectionné reste inchangé. la valeur du poids sélectionné du poids actuel est obtenue. {5-7,1,1}5. Lorsque la deuxième demande arrive, nous continuons les étapes 2, 3 et 4 ci-dessus Si vous ne le faites toujours pas. Si je ne comprends pas ici, je vais fournir mon propre code Java ci-dessous. Algorithme implémenté : Le résultat de l'exécution du code ici est : On peut voir que le résultat de l'exécution ici est cohérent avec le résultat décrit dans le tableau.
demande poids actuel = propre poids + poids actuel après sélection poids total poids maximum actuel IP retourné Poids actuel après sélection = poids maximum actuel - poids total
{-2, 1,3 ,3} 7 3 192.168.1.2 {1,-4,3}
{6,-3,4} 9.1.1 .1.3 {4,-2,-2} 6 {9,-1,-1} 7
192.168.1.1 {2,-1,-1} 7 {7,0,0} 7
192.168.1.1 {0,0,0}
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;
  }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer