权重轮询调度算法(Weighted Round-Robin Scheduling)-C#实现
参考:https://www.cnblogs.com/yunh/p/3172716.html
/// <summary>
/// 权重轮询算法
/// </summary>
public static class WeightedRoundRobin
{
private static readonly List<Server> s = new List<Server>()
{
new Server()
{
IP = "192.168.0.100",
Weight = 3
},
new Server()
{
IP = "192.168.0.101",
Weight = 2
},
new Server()
{
IP = "192.168.0.102",
Weight = 6
},
new Server()
{
IP = "192.168.0.103",
Weight = 4
},
new Server()
{
IP = "192.168.0.104",
Weight = 1
},
}.OrderBy(a => a.Weight).ToList();
private static int i = -1;//代表上一次选择的服务器
private static readonly int gcd = GetGcd(s);//表示集合S中所有服务器权值的最大公约数
private static int cw = 0;//当前调度的权值
private static readonly int max = GetMaxWeight(s);
private static readonly int n = s.Count;//服务器个数
/**
* 算法流程:
* 假设有一组服务器 S = {S0, S1, …, Sn-1} (n>1)(Sn-1的权重<Sn的权重)
* 变量i表示上次选择的服务器,如上次所选为权重最大服务器,则本次所选为权重最小服务器,所有服务器权值的最大公约数为每次步长
* 权值cw初始化为0,i初始化为-1 ,当第一次的时候 权值取最大的那个服务器,
* 通过权重的不断递减 只要服务器权重大于等于当前权重 则服务器返回(即权重越大的服务器,被选择的机会越多),直到轮询结束,权值返回为0
*/
public static Server? GetServer()
{
while (true)
{
i = (i + 1) % n;
if (i == 0)
{
cw -= gcd;
if (cw <= 0)
{
cw = max;
if (cw == 0)
return default;
}
}
if (s[i].Weight >= cw)
{
return s[i];
}
}
}
/// <summary>
/// 获取服务器所有权值的最大公约数
/// </summary>
/// <param name="servers"></param>
/// <returns></returns>
private static int GetGcd(List<Server> servers)
{
return servers.Select(s => s.Weight).Aggregate(GCD);
}
private static int GCD(int a, int b)
{
return b == 0 ? Math.Abs(a) : GCD(b, a % b);
}
/// <summary>
/// 获取最大的权值
/// </summary>
/// <param name="servers"></param>
/// <returns></returns>
private static int GetMaxWeight(List<Server> servers)
{
return servers.Max(s => s.Weight);
}
}
/// <summary>
/// 服务器结构
/// </summary>
public class Server
{
public string? IP;
public int Weight;
}
class Program
{
static void Main(string[] args)
{
Dictionary<string, int> dic = new();
Server? s;
for (int j = 0; j < 100; j++)
{
s = WeightedRoundRobin.GetServer();
Console.WriteLine("{0},weight:{1}", s.IP, s.Weight);
if (!dic.ContainsKey("服务器" + s.IP + ",权重:" + s.Weight))
{
dic.Add("服务器" + s.IP + ",权重:" + s.Weight, 0);
}
dic["服务器" + s.IP + ",权重:" + s.Weight]++;
}
foreach (var i1 in dic)
{
Console.WriteLine("{0}共处理请求{1}次", i1.Key, i1.Value);
}
Console.ReadLine();
}
}