Celery v4无法按预期方式路由任务

时间:2019-02-24 06:43:51

标签: python django celery

我正在将celery工人从celery v3更新到celery v4,我的所有任务都是 基于类的任务 I have manually registered the tasks,因为它是升级文档中指示的内容。

问题出在任务路由中,我有以下 Task

class RegisterTask(Task):
    routing_key = 'app_server.register'

    def run(**params):
        whatever ...

我正在运行两个芹菜工人,一个在默认队列中,另一个在寄存器队列中,如下所示:

# Default Worker
celery -A app_server worker --loglevel=info --concurrency=1

# Register Worker
celery -A app_server worker -Q app_server_register --loglevel=info --concurrency=1

这是我的队列定义:

CELERY_TASK_DEFAULT_QUEUE = 'app_server_default'
CELERY_TASK_DEFAULT_ROUTING_KEY = 'app_server.default'

CELERY_TASK_QUEUES = (
    Queue('app_server_default', routing_key='app_server.default'),
    Queue('app_server_register', routing_key='app_server.register')
)

意外的行为是当我使用Celery V3和Celery V4调用任务时看到的差异。

# Celery V3
RegisterTask().delay(**params)
# task is consumed by the register worker!

# Celery V4
RegisterTask().delay(**params)
# task is consumed by the default worker!

并且我希望任务由注册工作人员(celery v3行为)使用,因此为什么我在基于类的任务中硬编码了 routing_key 属性。但是Celery V4似乎忽略了基于类的任务中的 routing_key 属性。

[如果有任何重要意义,我也将 redis 用作经纪人]

对这个问题有任何想法吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

在第4版中不推荐使用

routing_key作为类属性。

您可以将其提供给调用时的任务 将其设置为apply_async,也可以在celery配置中手动将路由任务类型配置为队列。 参见docs


celery.task.base.Task中不推荐使用celery.app.task.Task中的Task类。

这是一项设计更改,新的Task类更喜欢在使用任务时而不是在实例化时绑定配置。 参见this comment

使用routing_key绑定任务时,通过浏览源可以看到_get_exec_options已设置。 Here个选项是使用实例(self)而不是类来设置的。

我通过查看celery源代码收集了这些信息,但是如果文档中没有提及过时,我想它们已经过时了。

也许最好在他们的github上填写问题并使用新范例中提供的选项之一。


  

文档中还有从任务元数据中读取任务routing_key的消息,因此基于类的任务不再可以具有此元数据了吗?

正确的,元数据不再位于类对象上。在调用时,它是通过config设置的,也可以是通过任务实例来设置的。

配置文件应该是静态路由的goto,而任务调用上的设置应该用于覆盖配置的默认值。