在多台机器实现负载均衡的时候,存在调度分配的问题.
如果服务器的配置的处理能力都一致的话,平均轮询分配可以直接解决问题,然而有些时候机器的处理能力是不一致的.
假如有2台机器 A和B , A的处理能力是B的2倍,则A的权重为2,B的权重为1.权值高的服务器先收到的连接,权值高的服 务器比权值低的服务器处理更多的连接,相同权值的服务器处理相同数目的连接数。
算法的C#版如下:
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 namespace TestConsoleApplication 6 { 7 /// <summary> 8 /// 权重轮询算法 9 /// </summary> 10 public static class WeightedRoundRobin 11 { 12 13 private static List<Server> s = new List<Server>() 14 { 15 new Server() 16 { 17 IP = "192.168.0.100", 18 Weight = 3 19 }, 20 new Server() 21 { 22 IP = "192.168.0.101", 23 Weight = 2 24 }, 25 new Server() 26 { 27 IP = "192.168.0.102", 28 Weight = 6 29 }, 30 new Server() 31 { 32 IP = "192.168.0.103", 33 Weight = 4 34 }, 35 new Server() 36 { 37 IP = "192.168.0.104", 38 Weight = 1 39 }, 40 }.OrderBy(a => a.Weight).ToList(); 41 42 private static int i = -1;//代表上一次选择的服务器 43 private static int gcd = GetGcd(s);//表示集合S中所有服务器权值的最大公约数 44 private static int cw = 0;//当前调度的权值 45 private static int max = GetMaxWeight(s); 46 private static int n = s.Count;//服务器个数 47 48 49 /** 50 * 算法流程: 51 * 假设有一组服务器 S = {S0, S1, …, Sn-1} ,有相应的权重,变量I表示上次选择的服务器,1每次步长 52 * 权值cw初始化为0,i初始化为-1 ,当第一次的时候 权值取最大的那个服务器, 53 * 通过权重的不断递减 寻找 适合的服务器返回,直到轮询结束,权值返回为0 54 */ 55 public static Server GetServer() 56 { 57 while (true) 58 { 59 i = (i + 1) % n; 60 if (i == 0) 61 { 62 cw = cw - gcd; 63 if (cw <= 0) 64 { 65 cw = max; 66 if (cw == 0) 67 return null; 68 } 69 } 70 if (s[i].Weight >= cw) 71 { 72 return s[i]; 73 } 74 } 75 } 76 77 78 /// <summary> 79 /// 获取服务器所有权值的最大公约数 80 /// </summary> 81 /// <param name="servers"></param> 82 /// <returns></returns> 83 private static int GetGcd(List<Server> servers) 84 { 85 return 1; 86 } 87 /// <summary> 88 /// 获取最大的权值 89 /// </summary> 90 /// <param name="servers"></param> 91 /// <returns></returns> 92 private static int GetMaxWeight(List<Server> servers) 93 { 94 int max = 0; 95 foreach (var s in servers) 96 { 97 if (s.Weight > max) 98 max = s.Weight; 99 } 100 return max; 101 } 102 } 103 /// <summary> 104 /// 服务器结构 105 /// </summary> 106 public class Server 107 { 108 public string IP; 109 public int Weight; 110 } 111 112 113 class Program 114 { 115 static void Main(string[] args) 116 { 117 Dictionary<string, int> dic = new Dictionary<string, int>(); 118 Server s; 119 for (int j = 0; j < 100; j++) 120 { 121 s = WeightedRoundRobin.GetServer(); 122 Console.WriteLine("{0},weight:{1}", s.IP, s.Weight); 123 124 if (!dic.Keys.Contains("服务器" + s.IP + ",权重:" + s.Weight)) 125 dic.Add("服务器" + s.IP + ",权重:" + s.Weight, 0); 126 dic["服务器" + s.IP + ",权重:" + s.Weight]++; 127 } 128 129 foreach (var i1 in dic) 130 { 131 Console.WriteLine("{0}共处理请求{1}次", i1.Key, i1.Value); 132 } 133 134 Console.ReadLine(); 135 } 136 }
运行结果:
运行100次的结果统计: