带有 RabbitMQ 的 Celery:AttributeError:“DisabledBackend”对象没有属性“_get_task_meta_for”

Posted

技术标签:

【中文标题】带有 RabbitMQ 的 Celery:AttributeError:“DisabledBackend”对象没有属性“_get_task_meta_for”【英文标题】:Celery with RabbitMQ: AttributeError: 'DisabledBackend' object has no attribute '_get_task_meta_for' 【发布时间】:2014-06-06 13:48:14 【问题描述】:

我正在运行First Steps with Celery Tutorial。

我们定义以下任务:

from celery import Celery

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

@app.task
def add(x, y):
    return x + y

然后调用它:

>>> from tasks import add
>>> add.delay(4, 4)

但我收到以下错误:

AttributeError: 'DisabledBackend' object has no attribute '_get_task_meta_for'

我正在运行 celery worker 和 rabbit-mq 服务器。相当奇怪的是,celery worker 报告任务成功:

[2014-04-22 19:12:03,608: INFO/MainProcess] Task test_celery.add[168c7d96-e41a-41c9-80f5-50b24dcaff73] succeeded in 0.000435483998444s: 19 

为什么这不起作用?

【问题讨论】:

作为 Celery 和 RabbitMQ(或任何您想学习的库)的新用户,在学习教程时看到错误不会激发对软件质量的信心。这简直令人沮丧。我想学习如何使用你的库,而不是它的变通方法。 【参考方案1】:

继续阅读教程。将在Keep Results一章中解释。

要启动 Celery,您只需要提供 broker 参数,这是发送有关任务的消息所必需的。如果要检索有关已完成任务返回的状态和结果的信息,则需要设置 backend 参数。你可以在Configuration docs: CELERY_RESULT_BACKEND找到完整的列表和描述。

【讨论】:

我按照教程没有遇到任何问题,但仍然遇到这个错误并且很难纠正它。我在一个 Ubuntu 终端窗口中运行 Celery,然后在一秒钟内运行 Python 解释器。在第一个窗口中,我添加了 backend='rpc://' 并重新启动了 Celery。但是 Python 在第二个窗口中并没有意识到这种变化。在我按下 Ctrl+d 杀死 Python 并再次启动 Python 后,它工作正常。 我收到了 404,其中包含您答案中的最后一个链接。 @BryanOakley 我已经更新了链接。但是,Celery v4 在此处更改了设置,因此请谨慎操作。 @SteveSaporta 很有帮助的评论!这个小细节应该在文档中提到。 这里的问题是您不应该需要指定result_backend 来简单地返回AsyncResult 实例。 (这是.delay() 返回的内容。)result_backend 只需要查看该结果的属性,例如.status【参考方案2】:

我建议看看: http://www.cnblogs.com/fangwenyu/p/3625830.html

在那里你会看到 而不是

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

你应该写

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

就是这样。

【讨论】:

【参考方案3】:

万一有人像我一样容易犯错:教程没有说得这么明确,但是那一行

app = Celery('tasks', backend='rpc://', broker='amqp://')

是您的tasks.py 文件中的行的编辑。我的现在是:

app = Celery('tasks', backend='rpc://', broker='amqp://guest@localhost//')

当我从命令行运行 python 时,我得到:

$ python
>>> from tasks import add
>>> result = add.delay(4,50)
>>> result.ready()
>>> False

所有教程都应该易于理解,即使有点醉了。到目前为止,这个还没有达到那个标准。

【讨论】:

好吧,当您按照教程进行操作时,请记住,在编辑完tasks.py 后,您还必须从tasks 模块重新导入add 函数!基本上,尽管 add() 中的后端分配正确,但我一直收到这个错误,直到我在控制台中退出 Python (>>>quit()),回到它 ($python) 并从任务 import add 重新输入。 同意,一个糟糕的教程。 好吧,5 年后仍然令人困惑!我刚刚打开了pull-request 并添加了一个新句子来解决这个问题【参考方案4】:

教程不清楚的是tasks.py模块需要编辑,以便您更改行:

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

包含 RPC 结果后端:

app = Celery('tasks', backend='rpc://', broker='pyamqp://')

完成后,Ctrl + C celery worker 进程并重启它:

celery -A tasks worker --loglevel=info

本教程令人困惑,因为我们假设应用程序对象的创建是在客户端测试会话中完成的,但事实并非如此。

【讨论】:

这让我陷入困境。谢谢。【参考方案5】:

在您的项目目录中找到设置文件。

然后:sudo vim settings.py 复制/粘贴到 settings.py: CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend'

注意:如果您使用 django-celery 作为后端来存储队列中的消息。

【讨论】:

我在删除 backend_result=rpc 时遇到了这个问题(即依赖默认结果后端,即无),然后重复调用 result.ready()【参考方案6】:

Celery 依赖后端和代理。 这仅使用 Redis 为我解决了这个问题:

app = Celery("tasks", backend='redis://localhost',broker="redis://localhost")

记得修改配置后在终端重启worker

【讨论】:

【参考方案7】:

我遇到了同样的问题,为我解决的问题是在你的应用程序的 init 函数中导入 celery 文件 (celery.py),如下所示:

from .celery import CELERY_APP as celery_app

__all__ = ('celery_app',)

如果您使用 here 所述的 celery.py 文件

【讨论】:

以上是关于带有 RabbitMQ 的 Celery:AttributeError:“DisabledBackend”对象没有属性“_get_task_meta_for”的主要内容,如果未能解决你的问题,请参考以下文章

Celery+Rabbitmq实现异步任务

Celery+RabbitMQ+Redis

Celery + RabbitMQ +“发生套接字错误”

Celery 任务计划(Celery、Django 和 RabbitMQ)

celery+rabbitmq基本使用

Celery:使用 PostgreSQL 而不是 RabbitMQ