python使用itertools cycle实现RR(round robin)轮询接口

说起RR (round robin)平均轮询,我想大家都知道的,常见的负载均衡服务器,比如 nginx、haproxy、lvs 都是支持轮询调度的…   公司有几个高人现着手开发公网爬虫的架构,分布式的http代理。   我这边会大量的调用他的http代理,这就用到了轮询,但是有个问题是 我的程序架构是 多进程加多线程。不能很好的做好统一和线程安全的轮询获取方式。  统一轮询带来的好处,可以让单个ip被访问的频次最低,这样 一个大轮询下来,最初的代理ip是鲜活的。 如果你的程序是把所有的代理做随机,很有可能在短时间内,用同一个代理出去,流量大的话,很有可能被封堵ip。    

辛辛苦苦写得文章总是跑到别的网站上,标记下博客的链接..    http://xiaorui.cc/?p=1385    http://xiaorui.cc


实现RR轮询的方式还是很多的,比如最简单的 每次pop一个数据,就马上回塞到队列里面,总之保证队列是满的。   另外说下,这个时候列表推荐用双端队列deque,性能的损耗要比普通的list低的多。    我这里用的是 itertools里面的cycle功能。  创建一个迭代器,然后不停的顺序调度。 一般来说用了cycle之后是无停止的迭代器,So  用yield来做适当的停顿,在用next() 来进行下个数据。 

我已经把代码推到了github上, 功能虽然很小,但是有需要的朋友可以用用。  后期我会用tornado开发一个针对round robin轮询方案 。   代码如下…. …

https://github.com/rfyiamcool/py_round_robin

大家也可以直接pypi上下载,安装方式如下….. 

pip install py_round_robind

#!/usr/bin/python
#blog: xiaorui.cc
#author: rfyiamcool@163.com

from itertools import *
class Round_Robin():

    def __init__(self,data):
        self.data = data
        self.data_rr = self.get_item()

    def cycle(self,iterable):
        saved = []
        for element in iterable:
            yield element
            saved.append(element)
        while saved:
            for element in saved:
                yield element

    def get_item(self):
        count = 0
        for item in self.cycle(self.data):
            count += 1
            yield (count, item)

    def get_next(self):
        return self.data_rr.next()
        

if __name__ == "__main__":
    rr_obj = Round_Robin(['a','b','c'])
    for i in range(50):
        print rr_obj.get_next()
    

这是py_round_robin使用的方法,代码本身就很简单,用起来也相当的简单。   我这边已经在多线程下测试了,是可以保证线程安全的,不会出现数据乱跳的情况. ……




from py_round_robin import Round_Robin
rr_obj = Round_Robin(['a','b','c'])
for i in range(50):
    print rr_obj.get_next()

测试的结果,会发现他的结果是我们想要的….



[ruifengyun@spiderman rr (master ✗)]$ python Round_Robin.py
(1, 'a')
(2, 'b')
(3, 'c')
(4, 'a')
(5, 'b')
(6, 'c')
(7, 'a')
(8, 'b')
(9, 'c')
(10, 'a')
(11, 'b')
(12, 'c')
(13, 'a')
(14, 'b')
(15, 'c')
(16, 'a')
(17, 'b')
(18, 'c')
(19, 'a')
(20, 'b')
(21, 'c')
(22, 'a')
(23, 'b')
(24, 'c')
(25, 'a')
(26, 'b')
(27, 'c')
(28, 'a')

如果有更有想实现加权 weight的算法,那么最简单的方式就是构造函数的时候,多加入一个元素,这样会提供他的命中的几率…. ….



大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

3 Responses

  1. bravo 2016年2月4日 / 下午9:44

    so great !!!!!

  2. 漫步者 2015年5月11日 / 上午7:55

    好精细的模块哈。

发表评论

邮箱地址不会被公开。 必填项已用*标注