Polling load balancing

polling

The main idea is to pick a server of a service

1 simple implementation

public class RoundRobin {
    private static Integer pos = 0;

    public static String getServer() {
        if(pos >= ServerIps.LIST.size()) {
            pos = 0;
        }

        String ip = ServerIps.LIST.get(pos);
        pos++;
        return ip;
    }

    public static void main(String[] args) {
        for(int i = 0; i < 20; i++) {
            System.out.println(getServer());
        }
    }

}

2 Optimization: Considering Weight

When considering weight

  1. Violence to resolve, will create a LIST =, the IP address into the inside LIST according to the size of the weights
  2. Or in accordance with the idea of ​​stochastic optimization

Wherein A, B, C represent the three IP addresses, weights are 5,3,2 A: 5 B: 3 C: 2

Mapped to the coordinate axis
0 ----- --- 8--10. 5

offset value of another is not a random number, but 0,1,2,3,4,5,6,7,8,9

1 ——> A
2 ——> A 
...
6 ——> B
...

Code

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


public class ServerIps {

    public static final Map<String, Integer> WEIGHT_MAP = new LinkedHashMap<>();
    static {
        WEIGHT_MAP.put("192.168.0.1", 2);
        WEIGHT_MAP.put("192.168.0.2", 8);
        WEIGHT_MAP.put("192.168.0.3", 1);
        WEIGHT_MAP.put("192.168.0.4", 9);
        WEIGHT_MAP.put("192.168.0.5", 4);
        WEIGHT_MAP.put("192.168.0.6", 6);
    }

}

Note employed therein is a LinkedHashMap , so that the order can ensure consistent output and input

public class RequestId {
    public static Integer num = 0;

    public static Integer getAndIncrement() {
        return num++;
    }

}

Imitate the above code is the customer ID number to control the polling of the server according to the customer ID number.

public class RoundRobin2 {
public static String getServer() {

        int totalWeight = 0;
        for (Integer weight: ServerIps.WEIGHT_MAP.values()) {
            totalWeight += weight;
        }

        int requestId = RequestId.getAndIncrement();
        int offset = requestId % totalWeight;

        for(String ip: ServerIps.WEIGHT_MAP.keySet()) {
            Integer weight = ServerIps.WEIGHT_MAP.get(ip);
            if (offset < weight) {
                return ip;
            }

            offset -= weight;
        }
        return null;

    }

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            System.out.println(getServer());
        }
    }

}

Optimization 3: smoothing algorithm WRR

Nginx default using this algorithm

A:. 5
B: 1
C: 1 In this case, the access order optimized as a AAAAABC, so pressure on the server A relatively large 

If in discrete, then there would be such a problem, such as the following order
AABACAA
This will not only make the service more scattered, but also to ensure the weight, but also to achieve the purpose of polling

Specific process is as follows:

ip
weight: static, 5,1,1 currentWeight: Dynamic

currentWeight: 0,0,0

 

currentWeight+=weight max(currentWeight) result max(currentWeight)-=sum(weight)7
5,1,1 5 A -2,1,1
3,2,2 3 A -4,2,2
1,3,3 3 B 1,-4,3
6,-3,4 6 A -1,-3,4
4,-2,5 5 C 4,-2,-2
9,-1,-1 9 A 2,-1,-1
7,0,0 7 A 0,0,0
5,1,1 ... ... ...

 

Code

public class Weight {
    private String ip;
    private Integer weight;
    private Integer currentWeight;

    public Weight(String ip, Integer weight, Integer currentWeight) {
        super();
        this.ip = ip;
        this.weight = weight;
        this.currentWeight = currentWeight;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getCurrentWeight() {
        return currentWeight;
    }

    public void setCurrentWeight(Integer currentWeight) {
        this.currentWeight = currentWeight;
    }

}

=============================

import java.util.LinkedHashMap;
import java.util.Map;

public class WeightRoundRobin {
    private static Map<String, Weight> weightMap = new LinkedHashMap<>();

    public static String getServer() {
        if(weightMap.isEmpty()) {
            for(String ip: ServerIps.WEIGHT_MAP.keySet()) {
                Integer weight = ServerIps.WEIGHT_MAP.get(ip);          
                weightMap.put(ip, new Weight(ip, weight, 0));

            }
        }
        // currentWeight += weight
        for(Weight weight: weightMap.values()) {
            weight.setCurrentWeight(weight.getCurrentWeight() + weight.getWeight());
        }

        Weight maxCurrentWeight = null;
        for (Weight weight: weightMap.values()) {
            if (maxCurrentWeight == null || weight.getCurrentWeight() > maxCurrentWeight.getCurrentWeight()) {
                maxCurrentWeight = weight;
            }
        }

        // max(currentWeight) -= sum(weight)
        int totalWeight = 0;
        for (Integer weight: ServerIps.WEIGHT_MAP.values()) {
            totalWeight += weight;
        }

        maxCurrentWeight.setCurrentWeight(maxCurrentWeight.getCurrentWeight() - totalWeight);

        //result
        return maxCurrentWeight.getIp();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println(getServer());
        }
    }
}

Guess you like

Origin www.cnblogs.com/Stephanie-boke/p/12289736.html