2种负载均衡算法

接口定义:

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

posted @ 2016-06-03 21:59  Joe·Zhou  阅读(460)  评论(0编辑  收藏  举报