簡體   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