1. 程式人生 > >c#版的smooth weighted round-robin balancing

c#版的smooth weighted round-robin balancing

分布 sys con pos dia eas string i++ test

Nginx基於權重的輪詢算法的實現,它不但實現了基於權重的輪詢算法,而且還實現了平滑的算法。
所謂平滑,就是在一段時間內,不僅服務器被選擇的次數的分布和它們的權重一致,而且調度算法還比較均勻的選擇服務器,而不會集中一段時間之內只選擇某一個權重比較高的服務器。
如果使用隨機算法選擇或者普通的基於權重的輪詢算法,就比較容易造成某個服務集中被調用壓力過大。

舉個例子,比如權重為{a:5, b:1, c:1)的一組服務器,Nginx的平滑的輪詢算法選擇的序列為{ a, a, b, a, c, a, a },
這顯然要比{ c, b, a, a, a, a, a }序列更平滑,更合理,不會造成對a服務器的集中訪問。

c#版本代碼如下:

/// <summary> 2 /// 權重對象 3 /// </summary> 4 public class WeightObject 5 { 6 /// <summary> 7 /// 當前權重 8 /// </summary> 9 public int CurrentWeight { set; get; } 10 11 /// <summary> 12 /// 有效 13 /// </summary>
14 public int EffectiveWeight { set; get; } 15 16 17 /// <summary> 18 /// 權重 19 /// </summary> 20 public int Weight { set; get; } 21 22 23 } 24 25 public class BalancingAssignHelper 26 { 27 28 /// <summary> 29 ///
算法: 30 /// on each peer selection we increase current_weight of each eligible peer by its weight, 31 ///select peer with greatest current_weight and reduce its current_weight by total number of weight points distribute damong peers. 32 public static T Next<T>(List<T> servers) where T : WeightObject 33 { 34 if (servers == null || servers.Count == 0) 35 { 36 return null; 37 } 38 if (servers.Count == 1) 39 { 40 return servers[0]; 41 } 42 43 T best = null; 44 45 //計算權重總和 46 int total = 0; 47 for (int i = 0; i < servers.Count; i++) 48 { 49 50 T w = servers[i]; 51 52 if (w == null) 53 { 54 continue; 55 } 56 57 w.CurrentWeight += w.EffectiveWeight; 58 total += w.EffectiveWeight; 59 60 if (w.EffectiveWeight < w.Weight) 61 { 62 w.EffectiveWeight++; 63 } 64 65 if (best == null || w.CurrentWeight > best.CurrentWeight) 66 { 67 best = w; 68 } 69 70 } 71 72 if (best == null) 73 { 74 return null; 75 } 76 77 best.CurrentWeight -= total; 78 return best; 79 } 80 } 81 82 //1.聲明一個繼承RandomObject的實體類,如:* 83 public class ServerWeightObject : WeightObject 84 { 85 /// <summary> 86 /// 名稱 87 /// </summary> 88 public string Name { set; get; } 89 /// <summary> 90 /// 描述 91 /// </summary> 92 public string Description { set; get; } 93 //...其它相關的字段/屬性 94 95 public ServerWeightObject() 96 { 97 EffectiveWeight = Weight; 98 } 99 } 100 101 102 /// <summary> 103 /// DEMO 104 /// </summary> 105 public class BalancingAssignDemo 106 { 107 108 public void Main() 109 { 110 111 //1.初始化調用數據,如: 112 List<ServerWeightObject> list = new List<ServerWeightObject>(); 113 list.Add(new ServerWeightObject { Name = "A", Weight = 2 }); 114 list.Add(new ServerWeightObject { Name = "B", Weight = 3 }); 115 list.Add(new ServerWeightObject { Name = "C", Weight = 5}); 116 //list.Add(new ServerWeightObject { Name = "D", Weight = 3 }); 117 //list.Add(new ServerWeightObject { Name = "E", Weight = 4 }); 118 //list.Add(new ServerWeightObject { Name = "F", Weight = 5 }); 119 //list.Add(new ServerWeightObject { Name = "G", Weight = 60 }); 120 for (int i = 0; i < 20; i++) 121 { 122 System.Diagnostics.Debug.Write(BalancingAssignHelper.Next<ServerWeightObject>(list).Name); 123 } 124 } 125 }

c#版的smooth weighted round-robin balancing