如何在Python-RQ中创建多个worker?

时间:2015-09-16 02:49:29

标签: python django redis task-queue python-rq

我们最近被迫用RQ取代芹菜,因为它更简单,芹菜给我们带来太多问题。现在,我们无法找到一种动态创建多个队列的方法,因为我们需要同时完成多个作业。因此,基本上我们对其中一条路线的每个请求都应该启动一项工作,让多个用户等待一个用户的工作完成后才能继续下一个工作是没有意义的。我们会定期向服务器发送请求,以获取作业和某些元数据的状态。通过这种方式,我们可以使用进度条更新用户(这可能是一个漫长的过程,因此必须为了UX而这样做)

我们正在使用Django和Python的rq库。我们没有使用django-rq(如果使用它有优势请告诉我)

到目前为止,我们在一个控制器中开始执行任务,例如:

redis_conn = Redis()
q = Queue(connection=redis_conn)  
job = django_rq.enqueue(render_task, new_render.pk, domain=domain, data=csv_data, timeout=1200)

然后在我们的render_task方法中,我们根据长任务的状态向作业添加元数据:

current_job = get_current_job()
current_job.meta['state'] = 'PROGRESS'
current_job.meta['process_percent'] = process_percent
current_job.meta['message'] = 'YOUTUBE'
current_job.save()

现在我们有另一个端点获取当前任务及其元数据并将其传递回客户端(这通过oeriodic AJAX请求发生)

我们如何在不阻碍其他工作的情况下同时运行工作?我们应该动态制作队列吗?有没有办法利用工人来实现这个目标?

3 个答案:

答案 0 :(得分:4)

据我所知,RQ没有任何设施来管理多个工人。您必须启动一个新的工作进程,以定义它将使用哪个队列。对我来说这样做的一种方法是使用Supervisor。在管理程序中,您可以为给定队列和进程数配置工作程序以实现并发。例如,您可以拥有排队"高优先级"有5名工人和队列"低优先级"与1名工人。

答案 1 :(得分:3)

我想使用django-rq建议一个非常简单的解决方案:

示例settings.py

...

RQ_QUEUES = {
    'default': {
        'HOST': os.getenv('REDIS_HOST', 'localhost'),
        'PORT': 6379,
        'DB': 0,
        'DEFAULT_TIMEOUT': 360,
    },
    'low': {
        'HOST': os.getenv('REDIS_HOST', 'localhost'),
        'PORT': 6379,
        'DB': 0,
        'DEFAULT_TIMEOUT': 360,
    }
}

...

运行配置

多次运行python manage.py rqworker default low(每次都在自己的shell中,或作为自己的Docker容器),作为所需工作者的数量。命令中的队列顺序决定了它们的优先级。此时,所有工作人员都在听两个队列。

代码

调用要运行的作业时,请传入所需的队列:

对于高优先级/普通优先级作业,您可以不带任何参数进行调用,作业将进入默认队列。对于低优先级,您必须在作业级别指定:

@job('low')
def my_low_priority_job():
  # some code

然后拨打my_low_priority_job.delay()

或者,在呼叫时确定优先级:

queue = django_rq.get_queue('low')
queue.enqueue(my_variable_priority_job)

答案 2 :(得分:0)

运行多个工人不仅是可行的,而且是理想的选择。我将bash文件用于start命令以输入虚拟env,并使用自定义Worker类启动。

这里的主管配置对于RQ工人来说对我来说非常有效,在生产工作负载下也是如此。请注意, startretries 很高,因为它在AWS上运行并且在部署期间需要重试。

[program:rq-workers]
process_name=%(program_name)s_%(process_num)02d
command=/usr/local/bin/start_rq_worker.sh
autostart=true
autorestart=true
user=root
numprocs=5
startretries=50
stopsignal=INT
killasgroup=true
stopasgroup=true
stdout_logfile=/opt/elasticbeanstalk/tasks/taillogs.d/super_logs.conf
redirect_stderr=true