主要实现了 轮询、加权轮询、随机、加权随机、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