19

总的来说,我对 celery 和 django 很陌生,所以请原谅我缺乏知识。我正在尝试运行测试以进行一些计算并等待测试完成,以便我可以确保它完成了正确的答案。

这是我所拥有的:

在 app/tests.py

from tasks import *


c = calculate.apply_async(args=[1])

# wait until the task is done
while not calculate.AsyncResult(c.id).status == "SUCCESS":
    print c.state
    pass

在应用程序/tasks.py

from celery import shared_task

@shared_task
def calculate(proj_id):

    #some calculations followed by a save of the object

即使在 celery 日志中表示任务已成功完成,状态也不会从挂起更改

[2014-06-10 17:55:11,417: INFO/MainProcess] Received task: app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac]
[2014-06-10 17:55:11,505: INFO/MainProcess] Task app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac] succeeded in 0.0864518239978s: None

我还在 mainapp/settings.py 中添加了 CELERY_IGNORE_RESULT = False,但这似乎没有任何作用。

4

3 回答 3

13

直接来自文档:结果后端不起作用或任务始终处于PENDING状态。

默认情况下,所有任务都是PENDING,因此将状态命名为“未知”会更好。发送任务时,Celery 不会更新任何状态,并且任何没有历史记录的任务都被假定为挂起(id毕竟您知道该任务)。

  1. 确保任务未ignore_result启用。

    启用此选项将强制工作人员跳过更新状态。

  2. 确保CELERY_IGNORE_RESULT未启用该设置。

  3. 确保您没有任何旧工人仍在运行。

    意外启动多个worker很容易,因此在启动新的worker之前,请确保前一个worker正确关闭。

    未配置预期结果后端的旧工作人员可能正在运行并劫持任务。

    可以将–pidfile参数设置为绝对路径以确保不会发生这种情况。

  4. 确保客户端配置了正确的后端。

如果由于某种原因客户端被配置为使用与工作人员不同的后端,您将无法接收结果,因此请通过检查后端来确保它是正确的:

>>> result = task.delay(…)
>>> print(result.backend)
于 2014-12-09T13:23:49.817 回答
6

所以,你的设置是错误的。:) 你还需要为 celery 设置一个代理才能工作。

首先,djcelery已弃用,所有内容都包含在celery其中以使其与django.

其次,不要将所有内容都设置为接受,这可能会带来潜在的安全风险。pickle仅在简单不够的情况下使用json(假设您将函数或对象作为参数传递给任务,或从任务返回)

所以我的猜测是,你只是在尝试 celery,这就是你尝试使用数据库后端的原因,这很好,但对于生产用途,我建议使用 RabbitMQ。

无论如何,请尝试以下设置:

BROKER_URL = 'django://'
INSTALLED_APPS = (
    ...
    'kombu.transport.django', 
    ...
)
CELERY_RESULT_BACKEND = 'db+scheme://user:password@host:port/dbname' 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False # this is less important

然后运行python manage.py syncdb

只是为了让您知道,我没有将数据库用作代理或结果后端,因此设置可能不完整,甚至不正确,但无论如何都要尝试一下。

数据库示例的更多CELERY_RESULT_BACKEND设置

如果您想将 RabbitMQ 设置为代理后端,我会推荐它并且我确信它会起作用:

如果在 ubuntu 上运行:

sudo apt-get install rabbitmq-server
sudo rabbitmqctl add_user <username> <password>
sudo rabbitmqctl add_vhost <vhost, use project name for example>
sudo rabbitmqctl set_permissions -p <vhost> <username"> ".*" ".*" ".*"

然后在中配置 celery settings.py

BROKER_URL = 'amqp://<user>:<password>@localhost:5672/<vhost>'
CELERY_TIMEZONE = TIME_ZONE
CELERY_RESULT_BACKEND = 'amqp'
# thats where celery will store scheduled tasks in case you restart the broker:
CELERYD_STATE_DB = "/full/path/data/celery_worker_state" 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

让我知道事情的后续。

于 2014-06-13T08:47:38.797 回答
0

如果您使用的是旧django-celeryRabbitMQ后端,那么这些设置可能会有所帮助:

# Mostly, all settings are the same as in other answers

CELERY_RESULT_BACKEND = 'rpc://'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False

# This line is what I needed
CELERY_TRACK_STARTED = True
于 2018-01-19T15:13:56.530 回答