2010-04-21 59 views
7

我需要编写一个循环算法来调度加载到n个端点吗?使用循环算法调度负载?

所以,如果我有服务器A,B和C

我想通过它们,以确保为round-robin每个请求我得到。我如何在C#中执行此操作?

+1

它是恒定负载还是你想要负载分配? – Avitus 2010-04-21 16:02:39

+0

我认为'循环赛'表示没有尝试均匀分配负载。 – 2010-04-21 16:13:53

回答

18

只是为了记录在案,循环赛的定义:

http://en.wikipedia.org/wiki/Round-robin_scheduling

只需使用一个队列。从顶部取一个,使用它并放回去。这确保了最近使用的那个将永远是最后一个被拾取的。

Queue<Server> q = new Queue<Server>(); 

//get the next one up 
Server s = q.DeQueue(); 


//Use s; 


//put s back for later use. 
q.Enqueue(s); 

链接到队列类:

http://msdn.microsoft.com/en-us/library/7977ey2c.aspx

+0

我会挑战一个人说他想实施循环法,以确定他们是否真的意味着循环赛。 – Tim 2010-04-21 16:23:39

+2

它一直用于服务器负载分配。 – kemiller2002 2010-04-21 16:26:57

+1

使用此模式时,在使用服务器之前立即排队服务器(或将入队放入finally块)可能是值得的。这样,在“使用”服务器期间抛出的任何异常都不会导致服务器完全从旋转中移除。 – bvoyelr 2015-09-16 12:52:54

1

如果您的终端是通过列表或数组访问,你只需要在一个循环的方式来增加一个索引:

public class RoundRobinIndex 
{ 
    volatile int index = 0; 
    int count; 

    public int Next 
    { 
     get 
     { 
      if (index == count) 
      { 
       index = 0; 
      } 
      return index++; 
     } 
    } 

    public RoundRobinIndex(int countArg) 
    { 
     count = countArg; 
    } 
} 
+0

使用它将导致IndexOutOfRangeException – IBootstrap 2013-08-21 05:31:45

+0

@IBootstrap - 它不会导致IndexOutOfRangeException。你真的测试过它吗? – 2014-07-11 16:54:15

+0

接下来还可以使用:(index + 1)%count来实现; – Aerokneeus 2015-10-26 17:11:22

6

与ebpower一样的想法,但关注的是下一个项目,而不是下一个项目的索引。

public class RoundRobinList<T> 
{ 
    private readonly IList<T> _list; 
    private readonly int _size; 
    private int _position; 

    public RoundRobinList(IList<T> list) 
    { 
     if (!list.Any()) 
      throw new NullReferenceException("list"); 

     _list = new List<T>(list); 
     _size = _list.Count;    
    } 

    public T Next() 
    { 
     if (_size == 1) 
      return _list[0]; 

     Interlocked.Increment(ref _position); 
     var mod = _position % _size; 
     return _list[mod]; 
    } 
} 
+0

将IEnumerable 传递给构造函数并在Incrementing _position之前记录mod,这就是金钱。 – JJS 2016-06-03 03:09:18