我正在构建分布式抓取机制,并希望确保在一分钟内向服务器发出的请求不超过30个。每个enqued任务都会发出请求。
所有任务都在redis中使用,并使用python-rq提供的api进行了解释。
方法是在每分钟到期的redis中设置一个密钥,以保存发送的请求数。
每当有一项工作可用时,检查是否发送了请求<三十 - 如果不是,那就睡一会儿 - 如果是,请继续工作
以下是我的自定义工作人员:
#!/usr/bin/env python
import sys
import time
from rq import Connection, Worker
from redis import Redis
redis = Redis()
def should_i_work():
r = redis.get('app:requests_sent_in_last_minute')
if r == None:
redis.setex('app:requests_sent_in_last_minute', 1, 60)
return r == None or int(r) < 30
def increment_requests():
r = int(redis.get('app:requests_sent_in_last_minute'))
redis.set('app:requests_sent_in_last_minute', r+1)
def main(qs):
with Connection():
try:
while True:
if should_i_work():
increment_requests()
w = Worker(qs)
w.work()
else:
time.sleep(60)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
qs = sys.argv[1:] or ['default']
main(qs)
这似乎不起作用,因为工作人员执行任务,尽管数字处于正常速度,并且所设置的密钥的值不会更新超过3。
我有一种强烈的感觉,我的思维过程是有缺陷的。我在这里做错了什么?
由于
答案 0 :(得分:0)
在审核了worker.py
来源后,我的思维过程中的错误显而易见。 w.work()
函数启动循环并连续出列任务。
因为无需重新编写worker类,所以无法控制此过程,下一个最好的方法是控制排队过程。如果在最后一分钟添加了30多个任务,请不要加入队列。
以下是我提出的解决方案:https://gist.github.com/shivekkhurana/7201e5cd2ec9d51af31c8b96eeb8fcf7
只需在RequestAwareWorker
标记中传递-w
。