权重轮询调度算法(Weighted Round-Robin Scheduling)-C#实现

在多台机器实现负载均衡的时候,存在调度分配的问题.

如果服务器的配置的处理能力都一致的话,平均轮询分配可以直接解决问题,然而有些时候机器的处理能力是不一致的.

假如有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次的结果统计:

参考:http://en.wikipedia.org/wiki/Weighted_round_robin

posted @ 2013-07-04 22:57  heyun  阅读(2192)  评论(0编辑  收藏  举报