码迷,mamicode.com
首页 > 编程语言 > 详细

实现一个简单的轮询算法

时间:2018-03-17 12:10:21      阅读:507      评论:0      收藏:0      [点我收藏+]

标签:均衡   字符串   get   log   ++   csharp   并行   exti   lock   

前言

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

实现一个简单的轮询算法

标签:均衡   字符串   get   log   ++   csharp   并行   exti   lock   

原文地址:https://www.cnblogs.com/catcher1994/p/simple_roundrobin.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!