Celery AsyncResult 始终处于待处理状态

Posted

技术标签:

【中文标题】Celery AsyncResult 始终处于待处理状态【英文标题】:Celery AsyncResult is always PENDING 【发布时间】:2014-09-20 16:03:19 【问题描述】:

我正在做一个演示,代码很简单:

# The Config
class Config:
    BROKER_URL = 'redis://127.0.0.1:6379/0'
    CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
    CELERY_ACCEPT_CONTENT = ['application/json']

# The Task
@celery_app.task()
def add(x, y):
    return x + y

启动worker:

$ celery -A appl.task.celery_app worker --loglevel=info -broker=redis://localhost:6379/0

 -------------- celery@ALBERTATMP v3.1.13 (Cipater)
 ---- **** ----- 
 --- * ***  * -- Linux-3.2.0-4-amd64-x86_64-with-debian-7.6
 -- * - **** --- 
 - ** ---------- [config]
 - ** ---------- .> app:         celery_test:0x293ffd0
 - ** ---------- .> transport:   redis://localhost:6379/0
 - ** ---------- .> results:     disabled
 - *** --- * --- .> concurrency: 2 (prefork)
 -- ******* ---- 
 --- ***** ----- [queues]
 -------------- .> celery           exchange=celery(direct) key=celery

要安排任务:

>>> from appl.task import add
>>> r = add.delay(1, 2)
>>> r.id
'c41d4e22-ccea-408f-b48f-52e3ddd6bd66'
>>> r.task_id
'c41d4e22-ccea-408f-b48f-52e3ddd6bd66'
>>> r.status
'PENDING'
>>> r.backend
<celery.backends.redis.RedisBackend object at 0x1f35b10>

然后worker会执行任务:

[2014-07-29 17:54:37,356: INFO/MainProcess] Received task: appl.task.add[beeef023-c582-42e1-baf7-9e19d9de32a0]
[2014-07-29 17:54:37,358: INFO/MainProcess] Task appl.task.add[beeef023-c582-42e1-baf7-9e19d9de32a0] succeeded in 0.00108124599865s: 3 

但是结果还是PENDING:

>>> res = add.AsyncResult(r.id)
>>> res.status
'PENDING'

我试过官方FAQ。但这并没有帮助。

>>> celery_app.conf['CELERY_IGNORE_RESULT']
False

我做错了什么?谢谢!

【问题讨论】:

你有没有弄清楚是什么导致了这个问题?我猜res.get 也会挂起? -broker=redis://localhost:6379/0 不能作为CELERY_RESULT_BACKEND 工作。实例化appl.task.celery_app时一定要传递backend='redis://127.0.0.1:6379/0' 【参考方案1】:

已经有一段时间了,但我把这个留给其他遇到类似问题的人:

在您的屏幕截图中,您会看到结果被禁用

当你实例化你的 celery 实例时,确保你有正确的配置输入

from celery import Celery,Task

# here im using an AMQP broker with a memcached backend to store the results
celery = Celery('task1',broker='amqp://guest:guest@127.0.0.1:5672//',backend='cache+memcached://127.0.0.1:11211/')

由于某种原因,我总是无法通过配置文件获取 celery 实例参数,因此在实例化过程中显式传递到代理和后端,如上所示

现在您将看到正确配置为 memcached 的结果(在我的实例中 - 在您的实例中应该是 redis)。还要确保你的任务在任务列表中被选中(task1.add)

如果你仍然不能让它工作,在启动 celery 时尝试使用下面的调试选项

celery worker -A task1.celery -l debug

看看它吐出的信息是否有问题

在我的情况下,它修复了您的错误,结果设置为成功,我能够在 r.get() 上恢复 3

【讨论】:

【参考方案2】:

    尝试将您的代理更改为其他内容(如rabbitmq)并再次检查状态。

    确保您的 redis 服务器已启动并可用于 celery。 redis-cli keys * 并且您应该会看到一些与 celery 相关的密钥,如果没有,则表示您的代理存在问题

【讨论】:

【参考方案3】:

这对我有用:

from celery.result import AsyncResult
celery_task_result = AsyncResult(task_id)
task_state = celery_task_result.state

task_state获得各种状态:'FAILURE''SUCCESS''PENDING'

【讨论】:

以上是关于Celery AsyncResult 始终处于待处理状态的主要内容,如果未能解决你的问题,请参考以下文章

如何取消芹菜队列上的任务? [复制]

芹菜 - 无法获取任务结果

即使在任务启动后,AsyncResult(task_id) 也会返回“PENDING”状态

MPNowPlayingInfoCenter 始终处于播放状态

Celery详解

Celery框架