C# 实现的几种负载均衡算法

主要实现了 轮询、加权轮询、随机、加权随机、IPHash

参考大佬文章:

https://www.cnblogs.com/wxd0108/p/5465938.html

废话不说,码上见

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    /// <summary>
    /// 负载均衡算法
    /// </summary>
    public class MyRoundRobin
    {
        // key=ip, val=权重
        static Dictionary<String, Int32> serverWeigthMap = new Dictionary<string, int>();

        static MyRoundRobin()
        {
            initData();
        }

        // 初始化数据
        private static void initData()
        {

        }

        /// <summary>
        /// 测试方法
        /// </summary>
        public static void Test()
        {
            var pls = new Collections.Concurrent.ConcurrentBag<String>();
            {
                var dic = new Dictionary<String, int>();
                {
                    dic.Add("192.168.1.12", 1);
                    dic.Add("192.168.1.13", 1);
                    dic.Add("192.168.1.14", 2);
                    dic.Add("192.168.1.15", 2);
                    dic.Add("192.168.1.16", 3);
                    dic.Add("192.168.1.17", 3);
                    dic.Add("192.168.1.18", 1);
                    dic.Add("192.168.1.19", 2);
                }

                // 初始化数据
                InitData(dic);

                Parallel.For(0, 200, item =>
                {
                    // 轮询
                    var str = MyRoundRobin.roundRobin();
                    // 加权轮询
                    //var str = MyRoundRobin.weightRoundRobin();
                    // 随机
                    //var str = MyRoundRobin.random();
                    // 加权随机
                    //var str = MyRoundRobin.weightRandom();
                    // ipHash
                    //var str = MyRoundRobin.ipHash("192.168.0." + item);
                    pls.Add(str);
                });

                pls.GroupBy(d => d)
                    .ToList()
                    .ForEach(str => Console.WriteLine($"{str.Key} cou={str.Count()}"));
            }
        }

        /// <summary>
        /// 初始化或更新数据
        /// </summary>
        public static void InitData(Dictionary<String, Int32> data)
        {
            foreach (var item in data)
            {
                serverWeigthMap.Add(item.Key, item.Value);
            }
        }

        private static Int32 pos = 0;
        private static object lockObj = new object();
        /// <summary>
        /// 轮询
        /// </summary>
        /// <returns></returns>
        public static String roundRobin()
        {
            //ip列表list
            var keySet = serverWeigthMap.Keys;
            String server = null;

            lock (lockObj)
            {
                // 重置索引
                if (pos >= keySet.Count)
                {
                    pos = 0;
                }

                server = keySet.ElementAt(pos);
                pos++;
            }

            return server;
        }

        private static Int32 pos2 = 0;
        private static object lockObj2 = new object();
        /// <summary>
        /// 加权轮询
        /// </summary>
        /// <returns></returns>
        public static String weightRoundRobin()
        {
            // ip列表list
            var keySet = serverWeigthMap.Keys;
            List<String> serverList = new List<String>();

            foreach (var item in keySet)
            {
                Int32 weight = serverWeigthMap[item];
                for (int i = 0; i < weight; i++)
                {
                    serverList.Add(item);
                }
            }

            String server = null;

            lock (lockObj2)
            {
                // 重置索引
                if (pos2 >= serverList.Count)
                {
                    pos2 = 0;
                }

                server = serverList[pos2];
                pos2++;
            }

            return server;
        }

        /// <summary>
        /// 加权随机
        /// </summary>
        /// <returns></returns>
        public static String weightRandom()
        {
            // ip列表list
            var keySet = serverWeigthMap.Keys;
            List<String> serverList = new List<String>();

            foreach (var item in keySet)
            {
                Int32 weight = serverWeigthMap[item];
                for (int i = 0; i < weight; i++)
                {
                    serverList.Add(item);
                }
            }

            Random random = new Random();
            int randomPos = random.Next(serverList.Count);

            String server = serverList[randomPos];
            return server;
        }

        /// <summary>
        /// 随机
        /// </summary>
        /// <returns></returns>
        public static String random()
        {
            // ip列表list
            var keySet = serverWeigthMap.Keys;

            Random random = new Random();
            int randomPos = random.Next(keySet.Count);

            String server = keySet.ElementAt(randomPos);
            return server;
        }

        /// <summary>
        /// IP Hash
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static String ipHash(String ip)
        {
            // ip列表list
            var keySet = serverWeigthMap.Keys;

            int hashCode = Math.Abs(ip.GetHashCode());
            int serverPos = hashCode % keySet.Count;

            return keySet.ElementAt(serverPos);
        }



    }
}

  

测试方法:

MyRoundRobin.Test();
            

 

over

 

上一篇:Java - 关于HashMap通过keySet遍历kv的二次调用问题


下一篇:2021-05-28 Map接口和常见方法