Django中的Celery任务总是阻塞的

1 投票
1 回答
1536 浏览
提问于 2025-04-18 10:22

我在我的Django设置中有以下配置:

CELERY_TASK_RESULT_EXPIRES = timedelta(minutes=30)
CELERY_CHORD_PROPAGATES = True
CELERY_ACCEPT_CONTENT = ['json', 'msgpack', 'yaml']
CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
BROKER_URL = 'django://'
CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend'

我把这个添加到了我的已安装应用列表里:

'djcelery',
'kombu.transport.django'

我的项目结构是这样的(Django 1.5):

proj
|_proj
  __init__.py
  celery.py      
  |_apps
    |_myapp1
      |_models.py
      |_tasks.py

这是我的 celery.py 文件:

from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings.dev')
app = Celery('proj')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS, related_name='tasks')

在主 __init__.py 文件中,我有:

from __future__ import absolute_import
from .celery import app as celery_app

最后,在 myapp1/tasks.py 中我定义了我的任务:

@task()
def retrieve():
  # Do my stuff

现在,如果我启动Django的交互式命令行,并运行 retrieve 任务:

result = retrieve.delay()

它似乎总是一个阻塞调用,这意味着在函数返回之前,命令行会被阻塞。result 状态是成功的,函数确实执行了操作,但它似乎不是异步的。我缺少了什么呢?

1 个回答

0

看起来 CELERY_ALWAYS_EAGER 这个设置会导致这个问题。

如果这个设置是开启的(True),那么所有的任务都会在本地执行,也就是说会一直等到任务完成后才继续进行。使用 apply_async() 和 Task.delay() 这两个方法时,会返回一个 EagerResult 实例,这个实例模仿了 AsyncResult 的接口和行为,但不同的是,结果已经被计算出来了。

也就是说,任务会在本地执行,而不是被发送到任务队列中去。

撰写回答