介面定義: 實現: 以上兩種方式均可以實現簡單的均衡演算法,第一種我參考許多前輩的寫法,第二種屬於自己想的.從概率論的角度出發都可以滿足需求,而且兩者效率相當(我原以為第二種實現方式速度更快,很遺憾的是結果證明並非如此,可能是Random對象取隨機數比較慢,我理論上認為沒有鎖會更快的),我個人覺得方法 ...
介面定義:
public interface ILoadBalance<T> { T Balance(); }
實現:
public class WeightObject<T> where T : class { int weight; T activator; public WeightObject(T activator, int weight) { Activator = activator; Weight = weight; } public int Weight { get { return weight; } private set { if (value <= 0) { throw new ArgumentOutOfRangeException(); } weight = value; } } public T Activator { get { return activator; } private set { if (value == null) { throw new ArgumentNullException(); } activator = value; } } } public class OrderLoadBalance<T> : ILoadBalance<T> { private readonly object syncRoot = new object(); private int gcd; private int currentIndex = -1; private int currentWeight = 0; private int maxWeight; private List<WeightObject<Func<T>>> list = new List<WeightObject<Func<T>>>(); public OrderLoadBalance(IEnumerable<WeightObject<Func<T>>> weightObjects) { list.AddRange(weightObjects); gcd = GetGCD(); maxWeight = list.Select(w => w.Weight).Max(); } private int GetGCD() { int gcd = 1; int minWeight = list.Select(w => w.Weight).Min(); for (int i = 1; i < minWeight; i++) { bool isFound = true; foreach (var weightObject in list) { if (weightObject.Weight % i != 0) { isFound = false; break; } } if (isFound) gcd = i; } return gcd; } [MethodImpl(MethodImplOptions.Synchronized)] public T Balance() { lock (syncRoot) { while (true) { currentIndex = (currentIndex + 1) % list.Count; if (0 == currentIndex) { currentWeight = currentWeight - gcd; if (0 >= currentWeight) { currentWeight = maxWeight; if (currentWeight == 0) return list[0].Activator(); } } if (list[currentIndex].Weight >= currentWeight) { return list[currentIndex].Activator(); } } } } } public class RandomLoadBalance<T> : ILoadBalance<T> {
private Random random; private int totalWeight; private List<WeightObject<Func<T>>> list = new List<WeightObject<Func<T>>>(); public RandomLoadBalance(IEnumerable<WeightObject<Func<T>>> weightObjects) { list.AddRange(weightObjects); totalWeight = list.Select(w => w.Weight).Sum(); random = new Random(); } public T Balance() { int r = random.Next(totalWeight) + 1; int weight = 0; foreach (var item in list) { weight += item.Weight; if (weight>=r) { return item.Activator(); } } return list[0].Activator();// } }
以上兩種方式均可以實現簡單的均衡演算法,第一種我參考許多前輩的寫法,第二種屬於自己想的.從概率論的角度出發都可以滿足需求,而且兩者效率相當(我原以為第二種實現方式速度更快,很遺憾的是結果證明並非如此,可能是Random對象取隨機數比較慢,我理論上認為沒有鎖會更快的),我個人覺得方法二更好,理由是離散型更好,方法一雖然概率上不錯,但是會連續密集的訪問同一對象.作為一種均衡演算法我覺得還是離散性高比較好,因為這樣可以更好的錯開密集訪問!!!