zoukankan      html  css  js  c++  java
  • 实现一个简单的轮询算法

    前言

    负载均衡,大家应该听的也不少了,也实践过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

  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/catcher1994/p/simple_roundrobin.html
Copyright © 2011-2022 走看看