繁体   English   中英

芹菜经纪人多个队列和工人

[英]celery one broker multiple queues and workers

我有一个名为tasks.py的python文件,其中定义了4个单个任务。 我想配置celery以便使用4个队列,因为每个队列将分配不同数量的工人。 我正在阅读我应该使用route_task属性,但是我尝试了几种选择,但没有成功。

我正在关注此文档celery route_tasks文档

我的目标是要运行4个工人,每个任务一个,并且不要将来自不同工人的任务混合在不同的队列中。 这是可能的? 这是一个好方法吗?

如果我做错了什么,我很乐意更改代码以使其正常工作

到目前为止,这是我的配置

task.py

app = Celery('tasks', broker='pyamqp://guest@localhost//')
app.conf.task_default_queue = 'default'
app.conf.task_queues = (
    Queue('queueA',    routing_key='tasks.task_1'),
    Queue('queueB',    routing_key='tasks.task_2'),
    Queue('queueC',    routing_key='tasks.task_3'),
    Queue('queueD',    routing_key='tasks.task_4')
)


@app.task
def task_1():
    print "Task of level 1"


@app.task
def task_2():
    print "Task of level 2"


@app.task
def task_3():
    print "Task of level 3"


@app.task
def task_4():
    print "Task of level 4"

为每个队列运行一位芹菜工人

celery -A tasks worker --loglevel=debug -Q queueA --logfile=celery-A.log -n W1&
celery -A tasks worker --loglevel=debug -Q queueB --logfile=celery-B.log -n W2&
celery -A tasks worker --loglevel=debug -Q queueC --logfile=celery-C.log -n W3&
celery -A tasks worker --loglevel=debug -Q queueD --logfile=celery-D.log -n W4&

无需为了将任务提交到不同的队列而进行复杂的路由。 照常定义任务。

from celery import celery

app = Celery('tasks', broker='pyamqp://guest@localhost//')

@app.task
def task_1():
    print "Task of level 1"


@app.task
def task_2():
    print "Task of level 2"

现在在排队任务时,将任务放入适当的队列中。 这是有关如何执行此操作的示例。

In [12]: from tasks import *

In [14]: result = task_1.apply_async(queue='queueA')

In [15]: result = task_2.apply_async(queue='queueB')

这会将task_1放入名为queueA队列中,并将task_2放入queueB

现在,您可以开始消耗您的工人。

celery -A tasks worker --loglevel=debug -Q queueA --logfile=celery-A.log -n W1&
celery -A tasks worker --loglevel=debug -Q queueB --logfile=celery-B.log -n W2&

注意: taskmessage在答案中可以互换使用。 它基本上是producer发送给RabbitMQ的有效载荷

您可以遵循Chillar建议的方法,也可以定义并使用task_routes配置将消息路由到适当的队列。 这样,您无需在每次调用apply_async都指定队列名称。

例如:路由TASK1QueueA和路由TASK2QueueB

app = Celery('my_app')
app.conf.update(
    task_routes={
        'task1': {'queue': 'QueueA'},
        'task2': {'queue': 'QueueB'}
    }
)

将任务发送到多个队列有点棘手。 您将必须声明交换,然后使用适当的routing_key路由任务。 您可以在此处获取有关交换类型的更多信息。 为了说明的目的,让我们direct进行。

  1. 创建交易所

     from kombu import Exchange, Queue, binding exchange_for_queueA_and_B = Exchange('exchange_for_queueA_and_B', type='direct') 
  2. 在队列上创建到该交换的绑定

     app.conf.update( task_queues=( Queue('QueueA', [ binding(exchange_for_queueA_and_B, routing_key='queue_a_and_b') ]), Queue('QueueB', [ binding(exchange_for_queueA_and_B, routing_key='queue_a_and_b') ]) ) ) 
  3. 定义task_route发送TASK1到交换

     app.conf.update( task_routes={ 'task1': {'exchange': 'exchange_for_queueA_and_B', 'routing_key': 'queue_a_and_b'} } ) 

您还可以按照上述答案中Chillar的建议,在apply_async方法中声明这些exchangerouting_key选项。

之后,您可以在同一台计算机或不同计算机上定义您的工作程序,以从这些队列中使用。

celery -A my_app worker -n consume_from_QueueA_and_QueueB -Q QueueA,QueueB
celery -A my_app worker -n consume_from_QueueA_only -Q QueueA

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM