权重轮巡、顺序轮巡、随机轮巡

实体

    public class SlaveConfiguration
    {
        public string ConnectionString { get; set; }

        public int Weight { get; set; }

        public int Attach { get; set; }
    }

轮巡算法接口

    public interface ILoadBalancing
    {
        /// <summary>
        /// 获取数据集合中的一条数据
        /// </summary>
        /// <param name="key">唯一标识,用于多数据库情况下的负载均衡</param>
        /// <param name="slaves">从库数据库连接字符串集合</param>
        /// <returns></returns>
        string NextConnectionString(string key, IReadOnlyList<SlaveConfiguration> slaves);
    }

随机轮巡算法

public class Randomer : ILoadBalancing
    {
        private readonly Random _random = new Random();

        public string NextConnectionString(string key, IReadOnlyList<SlaveConfiguration> slaves)
        {
            if (slaves == null || slaves.Count == 0)
            {
                throw new ArgumentNullException(nameof(slaves));
            }
            int count = slaves.Count;
            if (count == 1)
            {
                return slaves[0].ConnectionString;
            }
            return slaves[this._random.Next(count)].ConnectionString;
        }
    }

顺序轮巡算法

public class RoundRobiner : ILoadBalancing
    {
        private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

        private readonly ConcurrentDictionary<string, int> _indexDict = new ConcurrentDictionary<string, int>();

        public string NextConnectionString(string key, IReadOnlyList<SlaveConfiguration> slaves)
        {
            if (slaves == null || slaves.Count == 0)
            {
                throw new ArgumentNullException(nameof(slaves));
            }
            int count = slaves.Count;
            if (count == 1)
            {
                return slaves[0].ConnectionString;
            }
            string result = null;
            try
            {
                this._lock.Wait();

                key = $"{key}_{count}";

                int index = this._indexDict.GetOrAdd(key, 0);

                var slave = slaves[index];

                index++;
                if (index >= count)
                {
                    index = 0;
                }
                this._indexDict[key] = index;

                result = slave.ConnectionString;
            }
            finally
            {
                this._lock.Release();
            }
            return result;
        }
    }

权重轮巡算法

public class WeightedPoller : ILoadBalancing
    {
        private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

        public string NextConnectionString(string key, IReadOnlyList<SlaveConfiguration> slaves)
        {
            if (slaves == null || slaves.Count == 0)
            {
                throw new ArgumentNullException(nameof(slaves));
            }
            int count = slaves.Count;
            if (count == 1)
            {
                return slaves[0].ConnectionString;
            }
            string result = null;
            try
            {
                this._lock.Wait();
                int index = -1;
                int total = 0;
                for (var i = 0; i < count; i++)
                {
                    slaves[i].Attach += slaves[i].Weight;
                    total += slaves[i].Weight;
                    if (index == -1 || slaves[index].Attach < slaves[i].Attach)
                    {
                        index = i;
                    }
                }
                slaves[index].Attach -= total;
                result = slaves[index].ConnectionString;
            }
            finally
            {
                this._lock.Release();
            }
            return result;
        }
    }
posted @ 2020-05-10 11:54  .Neterr  阅读(436)  评论(0编辑  收藏  举报