接口定义:
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对象取随机数比较慢,我理论上认为没有锁会更快的),我个人觉得方法二更好,理由是离散型更好,方法一虽然概率上不错,但是会连续密集的访问同一对象.作为一种均衡算法我觉得还是离散性高比较好,因为这样可以更好的错开密集访问!!!