C#实现平滑加权轮询WeightedRoundRobin
2022/1/23 1:05:15
本文主要是介绍C#实现平滑加权轮询WeightedRoundRobin,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C#实现平滑加权轮询
作者:NewcatsHuang
时间:2022-01-22
完整代码:Github传送门
代码
WeightedRoundRobinHelper.cs
/// <summary> /// 平滑加权轮询(需要实例化为单例) /// </summary> /// <typeparam name="T">节点值类型</typeparam> public class WeightedRoundRobinHelper<T> { #region 字段 /// <summary> /// 最大公约数 /// </summary> private readonly int _gcd = 0; /// <summary> /// 最大权重值 /// </summary> private readonly int _maxWeight = 0; /// <summary> /// 节点数 /// </summary> private readonly int _nodesCount = 0; /// <summary> /// 当前权重 /// </summary> private int _currentWeight = 0; /// <summary> /// 上次选中的节点 /// </summary> private int _lastChosenNode = -1; /// <summary> /// 锁 /// </summary> private SpinLock _sLock = new SpinLock(true); /// <summary> /// 节点 /// </summary> private readonly List<WeightedNode<T>> _nodes; #endregion /// <summary> /// 当前所有节点按权重正序排列之后序列化的json字符串的md5值(System.Text.Json的默认配置) /// </summary> public string Md5Value { get; set; } /// <summary> /// 构造函数 /// </summary> /// <param name="nodes">节点</param> public WeightedRoundRobinHelper(List<WeightedNode<T>> nodes) { _nodes = nodes.OrderBy(q => q.Weight).ToList(); _gcd = GetGcd(_nodes); _maxWeight = GetMaxWeight(_nodes); _nodesCount = _nodes.Count; Md5Value = GetMd5(_nodes); } /// <summary> /// 获取此次选择结果 /// </summary> public WeightedNode<T> GetResult() { var isLocked = false; _sLock.Enter(ref isLocked); do { _lastChosenNode = (_lastChosenNode + 1) % _nodesCount; if (_lastChosenNode == 0) { _currentWeight -= _gcd; if (_currentWeight <= 0) { _currentWeight = _maxWeight; } } } while (_nodes[_lastChosenNode].Weight < _currentWeight); if (isLocked) { _sLock.Exit(true); } return _nodes[_lastChosenNode]; } /// <summary> /// 取权重的最大公约数(GreatestCommonDivisor) /// </summary> private int GetGcd(List<WeightedNode<T>> nodes) { int index = _lastChosenNode; if (index < 0) index = 0; int a = nodes[index].Weight; if (index >= _nodesCount - 1) index = -1; int b = nodes[index + 1].Weight; while (b != 0) { var t = b; b = a % b; a = t; } return a; } /// <summary> /// 取最大权重值 /// </summary> private int GetMaxWeight(List<WeightedNode<T>> nodes) { int max = nodes.Max(n => n.Weight); return max; } /// <summary> /// 取所有节点的json字符串的md5值(System.Text.Json的默认配置) /// </summary> private string GetMd5(List<WeightedNode<T>> nodes) { string json = System.Text.Json.JsonSerializer.Serialize(nodes); return EncryptHelper.MD5By32(json); } } /// <summary> /// 权重节点 /// </summary> public class WeightedNode<T> { /// <summary> /// 节点值 /// </summary> public T Value { get; set; } /// <summary> /// 初始权重 /// </summary> public int Weight { get; set; } }
测试
class Program { static void Main(string[] args) { var dic = new ConcurrentDictionary<string, int>(); var selector = new WeightedRoundRobinHelper<string>(new List<WeightedNode<string>> { new WeightedNode<string>(){ Value="1111111111111111", Weight=7}, new WeightedNode<string>(){ Value="2222222222222222", Weight=4}, new WeightedNode<string>(){ Value="3333333333333333", Weight=3}, new WeightedNode<string>(){ Value="4444444444444444", Weight=2}, new WeightedNode<string>(){ Value="5555555555555555", Weight=1}, }); Parallel.For(1, 100, (n) => { var s = selector.GetResult(); var key = $"节点:{s.Value}, 权重:{s.Weight}"; Console.WriteLine(key); dic.AddOrUpdate(key, 1, (k, v) => v + 1); }); Console.WriteLine("\r\n"); foreach (var kvp in dic) { Console.WriteLine($"{kvp.Key} 总计命中 {kvp.Value} 次"); } } }
结果
节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:2222222222222222, 权重:4 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:4444444444444444, 权重:2 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:2222222222222222, 权重:4 节点:4444444444444444, 权重:2 节点:3333333333333333, 权重:3 节点:2222222222222222, 权重:4 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:1111111111111111, 权重:7 节点:5555555555555555, 权重:1 节点:4444444444444444, 权重:2 节点:1111111111111111, 权重:7 总计命中 41 次 节点:3333333333333333, 权重:3 总计命中 17 次 节点:5555555555555555, 权重:1 总计命中 6 次 节点:2222222222222222, 权重:4 总计命中 23 次 节点:4444444444444444, 权重:2 总计命中 12 次
转载请注明出处,谢谢O(∩_∩)O
这篇关于C#实现平滑加权轮询WeightedRoundRobin的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#