• 实现一个简单的轮询算法


    前言

    负载均衡,大家应该听的也不少了,也实践过N次了。

    当然也会知道,负载均衡是有不少算法的:随机,轮询,加权轮询,最少连接。。。。

    本文重点说的是轮询。

    先举个例子看看轮询算法是如何运作的。

    假设我们的API站点有3台负载(10.0.10.1,10.0.10.2和10.0.10.3),客户端第一次请求API的时候,会访问.1拿到结果,第二次会访问.2拿到结果,第三次则会访问.3拿到结果,后面就是依次类推。

    在致就是这个样子的访问顺序。

    .1->.2->.3>.1>.2......

    当然,上面的情况是太太太理想了!!只是能帮助我们理解轮询是怎么一回事!

    下面是比较官方的描述:

    按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。

    下面来简单看看如何实现

    简单实现

    我们围绕的重点如下:

    1. 服务器列表
    2. 上一次访问的是那台机器
    3. 下一次要访问的是那台机器

    下面是实现

    public class RoundRobin<T>
    {
        //服务器列表
        private readonly IList<T> _items;
        
        //锁
        private readonly object _syncLock = new object();
        
        //当前访问的服务器索引,开始是-1,因为没有人访问
        private int _currentIndex = -1;
    
        public RoundRobin(IEnumerable<T> sequence)
        {
            _items = sequence.ToList();
    
            if(_items.Count <= 0 )
            {
                throw new ArgumentException("Sequence contains no elements.", nameof(sequence));
            }                           
        }
    
        public T GetNextItem()
        {
            lock (this._syncLock)
            {
                _currentIndex++;
                //超过数量,索引归0
                if (_currentIndex >= _items.Count)
                    _currentIndex = 0;
                return _items[_currentIndex];
            }
        }
    }
    

    根据用户不同的设计,服务器有可能是一个字符串,也有可能是自定义的一个类,所以设计成泛型参数会比较合适。

    下面测试一下

    static void Main(string[] args)
    {
        //负载的api地址
        var lbUrls = new List<string>
        {
            "http://10.0.10.1/api/values",
            "http://10.0.10.2/api/values",
            "http://10.0.10.3/api/values",
            "http://10.0.10.4/api/values",
        };
        
        //构造轮询的对象
        var robin = new RoundRobin<string>(lbUrls);
    
        //访问次数
        var visitCount = lbUrls.Count * new Random().Next(3, 5);
    
        //常规的情况
        Console.WriteLine("begin one by one..");
        for (int i = 0; i < visitCount; i++)
        {
            Console.WriteLine($"{i + 1}:Sending request to {robin.GetNextItem()}");
        }
        
        //并行的情况
        Console.WriteLine("begin parallel..");
        Parallel.For(0, visitCount, i =>
        {
            Console.WriteLine($"{i + 1}:Sending request to {robin.GetNextItem()}");
        });
    
        Console.ReadKey();
    }
    

    结果:

    示例代码:

    RoundRobinDemo

  • 相关阅读:
    C++ 练习02 魔术师发牌问题
    C++ 入门2 类型转换
    C++ 入门1 C++简介
    一个简单计算器的实现
    C++练习01 打印杨辉三角
    数据结构01数据结构基础01
    Lesson_7 作业_1 Driver 和 Car
    Caterl Java寒假基础练习题(一) 循环相加
    Lesson_9 上课笔记 多态
    Lesson_10 作业计算工资
  • 原文地址:https://www.cnblogs.com/catcher1994/p/simple_roundrobin.html
Copyright © 2020-2023  润新知