我跟着celery docs在我的开发机器上定义了2个队列。
我的芹菜设置:
CELERY_ALWAYS_EAGER = True
CELERY_TASK_RESULT_EXPIRES = 60 # 1 mins
CELERYD_CONCURRENCY = 2
CELERYD_MAX_TASKS_PER_CHILD = 4
CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_CREATE_MISSING_QUEUES = True
CELERY_QUEUES = (
Queue('default', Exchange('default'), routing_key='default'),
Queue('feeds', Exchange('feeds'), routing_key='arena.social.tasks.#'),
)
CELERY_ROUTES = {
'arena.social.tasks.Update': {
'queue': 'fs_feeds',
},
}
我在项目的virtualenv中打开了两个终端窗口,并运行以下命令:
terminal_1$ celery -A arena worker -Q default -B -l debug --purge -n deafult_worker
terminal_2$ celery -A arena worker -Q feeds -B -l debug --purge -n feeds_worker
我得到的是所有任务都由两个队列处理。
我的目标是让一个队列只处理CELERY_ROUTES
中定义的一个任务和默认队列来处理所有其他任务。
我也跟踪了这个SO question,rabbitmqctl list_queues
返回celery 0
,并且rabbitmqctl list_bindings
运行两次exchange celery queue celery []
。重启兔子服务器没有改变任何东西。
答案 0 :(得分:22)
好的,所以我想通了。以下是我的整个设置,设置以及如何运行芹菜,对于那些可能想知道与我的问题相同的人。
设置强>
CELERY_TIMEZONE = TIME_ZONE
CELERY_ACCEPT_CONTENT = ['json', 'pickle']
CELERYD_CONCURRENCY = 2
CELERYD_MAX_TASKS_PER_CHILD = 4
CELERYD_PREFETCH_MULTIPLIER = 1
# celery queues setup
CELERY_DEFAULT_QUEUE = 'default'
CELERY_DEFAULT_EXCHANGE_TYPE = 'topic'
CELERY_DEFAULT_ROUTING_KEY = 'default'
CELERY_QUEUES = (
Queue('default', Exchange('default'), routing_key='default'),
Queue('feeds', Exchange('feeds'), routing_key='long_tasks'),
)
CELERY_ROUTES = {
'arena.social.tasks.Update': {
'queue': 'feeds',
'routing_key': 'long_tasks',
},
}
如何经营芹菜?
终端 - 标签1:
celery -A proj worker -Q default -l debug -n default_worker
这将启动第一个使用默认队列任务的worker。注意! -n default_worker
不是第一个工作人员的必需品,但如果您有任何其他芹菜实例正在运行,则必须这样做。设置-n worker_name
与--hostname=default@%h
相同。
终端 - 标签2:
celery -A proj worker -Q feeds -l debug -n feeds_worker
这将启动第二个工作人员,消费者任务来自源队列。请注意-n feeds_worker
,如果您使用-l debug
(日志级别=调试)运行,您将看到两个工作人员正在它们之间进行同步。
终端 - 标签3:
celery -A proj beat -l debug
这将启动节拍,根据CELERYBEAT_SCHEDULE
中的计划执行任务。
我没有必要更改任务,或CELERYBEAT_SCHEDULE
。
例如,这是我的CELERYBEAT_SCHEDULE
查看应该进入Feed队列的任务的方式:
CELERYBEAT_SCHEDULE = {
...
'update_feeds': {
'task': 'arena.social.tasks.Update',
'schedule': crontab(minute='*/6'),
},
...
}
如您所见,无需添加'options': {'routing_key': 'long_tasks'}
或指定它应该进入哪个队列。此外,如果您想知道为什么Update
是大写的,那是因为它是一个自定义任务,它被定义为celery.Task
的子类。
答案 1 :(得分:1)
除了已接受的答案,如果有人来到这里仍然想知道为什么他的设置不起作用(就像我刚才所做的那样),原因如下:celery 文档没有正确列出设置名称。
对于 celery 5.0.5 设置 CELERY_DEFAULT_QUEUE
、CELERY_QUEUES
、CELERY_ROUTES
应该命名为 CELERY_TASK_DEFAULT_QUEUE
、CELERY_TASK_QUEUES
和 CELERY_TASK_ROUTES
。这些是我测试过的设置,但我的猜测是同样的规则也适用于交换和路由密钥。