• 轮询算法


    在多台机器实现负载均衡的时候,经常用到轮询调度算法(Round-Robin Scheduling)。

    轮询调度算法就是以循环的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。

    算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

    1、算法流程:
    假设有一组服务器 S = {S0, S1, …, Sn-1} ,有相应的权重,变量i表示上次选择的服务器,权值cw初始化为0,i初始化为-1 ,当第一次的时候取权值取最大的那个服务器,通过权重的不断递减,寻找适合的服务器返回,直到轮询结束,权值返回为0

     1 import java.math.BigInteger;
      2 import java.util.ArrayList;
      3 import java.util.HashMap;
      4 import java.util.List;
      5 import java.util.Map;
      6 import java.util.Map.Entry;
      7 
      8 /**
      9  * 权重轮询调度算法(WeightedRound-RobinScheduling)-Java实现
     10  * @author huligong
     11  * */
     12 public class WeightedRoundRobinScheduling {
     13 
     14     private int currentIndex = -1;// 上一次选择的服务器
     15     private int currentWeight = 0;// 当前调度的权值
     16     private int maxWeight = 0; // 最大权重
     17     private int gcdWeight = 0; //所有服务器权重的最大公约数
     18     private int serverCount = 0; //服务器数量
     19     private List<Server> serverList; //服务器集合
     20 
     21     /**
     22      * 返回最大公约数
     23      * @param a
     24      * @param b
     25      * @return
     26      */
     27     private static int gcd(int a, int b) {
     28         BigInteger b1 = new BigInteger(String.valueOf(a));
     29         BigInteger b2 = new BigInteger(String.valueOf(b));
     30         BigInteger gcd = b1.gcd(b2);
     31         return gcd.intValue();
     32     }
     33     
     34      
     35     /**
     36      * 返回所有服务器权重的最大公约数
     37      * @param serverList
     38      * @return
     39      */
     40     private static int getGCDForServers(List<Server> serverList ) {
     41         int w = 0;
     42         for (int i = 0, len = serverList.size(); i < len - 1; i++) {
     43             if (w == 0) {
     44                 w = gcd(serverList.get(i).weight, serverList.get(i + 1).weight);
     45             } else {
     46                 w = gcd(w, serverList.get(i + 1).weight);
     47             }
     48         }
     49         return w;
     50     }
     51     
     52 
     53     /**
     54      * 返回所有服务器中的最大权重
     55      * @param serverList
     56      * @return
     57      */
     58     public static int getMaxWeightForServers(List<Server> serverList) {
     59         int w = 0;
     60         for (int i = 0, len = serverList.size(); i < len - 1; i++) {
     61             if (w == 0) {
     62                 w = Math.max(serverList.get(i).weight, serverList.get(i + 1).weight);
     63             } else {
     64                 w = Math.max(w, serverList.get(i + 1).weight);
     65             }
     66         }
     67         return w;
     68     }
     69     
     70     /**
     71      *  算法流程: 
     72      *  假设有一组服务器 S = {S0, S1, …, Sn-1}
     73      *  有相应的权重,变量currentIndex表示上次选择的服务器
     74      *  权值currentWeight初始化为0,currentIndex初始化为-1 ,当第一次的时候返回 权值取最大的那个服务器,
     75      *  通过权重的不断递减 寻找 适合的服务器返回,直到轮询结束,权值返回为0 
     76      */
     77     public Server GetServer() {
     78         while (true) {
     79             currentIndex = (currentIndex + 1) % serverCount;
     80             if (currentIndex == 0) {
     81                 currentWeight = currentWeight - gcdWeight;
     82                 if (currentWeight <= 0) {
     83                     currentWeight = maxWeight;
     84                     if (currentWeight == 0)
     85                         return null;
     86                 }
     87             }
     88             if (serverList.get(currentIndex).weight >= currentWeight) {
     89                 return serverList.get(currentIndex);
     90             }
     91         }
     92     }
     93 
     94 
     95     class Server {
     96         public String ip;
     97         public int weight;
     98         public Server(String ip, int weight) {
     99             super();
    100             this.ip = ip;
    101             this.weight = weight;
    102         }
    103         public String getIp() {
    104             return ip;
    105         }
    106         public void setIp(String ip) {
    107             this.ip = ip;
    108         }
    109         public int getWeight() {
    110             return weight;
    111         }
    112         public void setWeight(int weight) {
    113             this.weight = weight;
    114         }
    115     }
    116     
    117 
    118     public void init() {
    119         Server s1 = new Server("192.168.0.100", 3);//3
    120         Server s2 = new Server("192.168.0.101", 2);//2
    121         Server s3 = new Server("192.168.0.102", 6);//6
    122         Server s4 = new Server("192.168.0.103", 4);//4
    123         Server s5 = new Server("192.168.0.104", 1);//1
    124         serverList = new ArrayList<Server>();
    125         serverList.add(s1);
    126         serverList.add(s2);
    127         serverList.add(s3);
    128         serverList.add(s4);
    129         serverList.add(s5);
    130         
    131         currentIndex = -1;
    132         currentWeight = 0;
    133         serverCount = serverList.size();
    134         maxWeight = getMaxWeightForServers(serverList);
    135         gcdWeight = getGCDForServers(serverList);
    136     }
    137     
    138     
    139     public static void main(String[] args) {
    140         WeightedRoundRobinScheduling obj = new WeightedRoundRobinScheduling();
    141         obj.init();
    142         
    143         Map<String,Integer> countResult = new HashMap<String,Integer>();
    144         
    145         for (int i = 0; i < 100; i++) {
    146             Server s = obj.GetServer();
    147             String log = "ip:"+s.ip+";weight:"+s.weight;
    148             if(countResult.containsKey(log)){
    149                 countResult.put(log,countResult.get(log)+1);
    150             }else{
    151                 countResult.put(log,1);
    152             }
    153             System.out.println(log);
    154         }
    155         
    156         for(Entry<String, Integer> map : countResult.entrySet()){
    157             System.out.println("服务器 "+map.getKey()+" 请求次数: "+map.getValue());
    158         }
    159     }
    160 
    161 }
    

      

  • 相关阅读:
    .NET正则基础之——平衡组
    正则基础之——贪婪与非贪婪模式
    正则应用之——日期正则表达式
    文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(完整版,收集,整理)
    linux c 发送邮件
    select, poll和epoll的区别(转)
    linux c 中文支持
    修改远程桌面连接端口(PortNumber)
    libhdfs编译,安装,配置,使用
    C语言字节对齐详解
  • 原文地址:https://www.cnblogs.com/fengli9998/p/6794989.html
Copyright © 2020-2023  润新知