Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 芹菜一个经纪人多个队列和工人_Python_Rabbitmq_Celery - Fatal编程技术网

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

Python 芹菜一个经纪人多个队列和工人,python,rabbitmq,celery,Python,Rabbitmq,Celery,我有一个名为tasks.py的python文件,其中定义了4个单独的任务。我想将芹菜配置为使用4个队列,因为每个队列将分配不同数量的工人。我正在阅读我应该使用route_任务属性,但我尝试了几个选项,但没有成功 我在跟踪这个医生 我的目标是运行4个工作人员,每个任务一个,不要在不同的队列中混合来自不同工作人员的任务。有可能吗?这是个好办法 如果我做错了什么,我会很乐意改变我的代码,使它工作 这是我到目前为止的配置 tasks.py app = Celery('tasks', broker='py

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

我在跟踪这个医生

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

如果我做错了什么,我会很乐意改变我的代码,使它工作

这是我到目前为止的配置

tasks.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')
这将把任务_1放在名为queueA的队列中,把任务_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&

将任务提交到不同的队列中不需要进行复杂的路由。像往常一样定义你的任务

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')
这将把任务_1放在名为queueA的队列中,把任务_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&
注意:任务和消息在回答中互换使用。它基本上是生产者发送给RabbitMQ的有效负载

您可以遵循Chillar建议的方法,也可以定义并使用task_routes配置将消息路由到适当的队列。这样,您就不需要每次调用apply\u async时都指定队列名称

示例:将task1路由到QueueA,将task2路由到QueueB

将任务发送到多个队列有点棘手。您必须声明交换,然后使用适当的路由密钥路由任务。您可以获得有关交换类型的更多信息。为了便于说明,让我们使用direct

创建交换

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

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')
        ])
    )
)
定义任务路由以将task1发送到exchange

app.conf.update(
    task_routes={
        'task1': {'exchange': 'exchange_for_queueA_and_B', 'routing_key': 'queue_a_and_b'}
    }
)
您还可以按照Chillar在上述答案中的建议,在apply_async方法中声明交换和路由_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
注意:任务和消息在回答中互换使用。它基本上是生产者发送给RabbitMQ的有效负载

您可以遵循Chillar建议的方法,也可以定义并使用task_routes配置将消息路由到适当的队列。这样,您就不需要每次调用apply\u async时都指定队列名称

示例:将task1路由到QueueA,将task2路由到QueueB

将任务发送到多个队列有点棘手。您必须声明交换,然后使用适当的路由密钥路由任务。您可以获得有关交换类型的更多信息。为了便于说明,让我们使用direct

创建交换

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

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')
        ])
    )
)
定义任务路由以将task1发送到exchange

app.conf.update(
    task_routes={
        'task1': {'exchange': 'exchange_for_queueA_and_B', 'routing_key': 'queue_a_and_b'}
    }
)
您还可以按照Chillar在上述答案中的建议,在apply_async方法中声明交换和路由_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

基本上我的问题是,与文档混淆,我使用的是3.x版本,使用的是4.x的文档…epic fail基本上我的问题是,与文档混淆,我使用的是3.x版本,使用的是4.x的文档…epic fail