Celery .delay() 同步工作,不延迟

Posted

技术标签:

【中文标题】Celery .delay() 同步工作,不延迟【英文标题】:Celery .delay() works synchronously, not delaying 【发布时间】:2019-06-01 10:05:51 【问题描述】:

我有一个具有 Celery 背景和定期任务的 Django 项目。我一年前开始工作进程,定期任务运行良好。但是,我刚刚发现调用异步函数主服务器代码不起作用,apply_async()/delay() 导致函数的同步执行就像不使用它们一样。我该如何解决这个问题?我的 Celery 版本是 4.2。这是我的 Celery 设置文件:

import os
from celery import Celery
from django.conf import settings

broker_url = 'amqp://<user>:<password>@localhost:5672/project'
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyProject.settings')

app = Celery('<project>', broker=broker_url)

app.config_from_object('django.conf:settings')
app.conf.update (
    CELERY_TASK_SERIALIZER='json',
    CELERY_ACCEPT_CONTENT=['json'],
    CELERY_RESULT_SERIALIZER='json',
    CELERYD_HIJACK_ROOT_LOGGER=False,
    BROKER_URL=broker_url,
    CELERY_RESULT_BACKEND='djcelery.backends.database.DatabaseBackend',
    CELERY_ALWAYS_EAGER=True,
)

这是我的测试代码:

from general.celery import app
from time import sleep

@app.task
def fun():
    for i in range(5):
        print('Sleeping')
        sleep(2)
    print('Awake')

def test():
    print('Begin')
    fun.apply_async(countdown=10)
    print('End')

它导致立即输出:

Begin
Sleeping
...

我还查看了 Celery 的 inspect:

from celery.task.control import inspect
print(inspect().stats())

它描述了以下状态:


    'broker': 
        'failover_strategy': 'round-robin',
        'ssl': False,
        'transport': 'amqp',
        'heartbeat': 120.0,
        'transport_options': ,
        'insist': False,
        'alternates': [],
        'connect_timeout': 4,
        'userid': '<user>',
        'hostname': '127.0.0.1',
        'login_method': 'AMQPLAIN',
        'port': 5672,
        'uri_prefix': None,
        'virtual_host': '<project>'
    ,
    'total': ,
    'prefetch_count': 8,
    'clock': '2299',
    'pool': 
        'put-guarded-by-semaphore': False,
        'max-concurrency': 2,
        'max-tasks-per-child': 'N/A',
        'writes': 
            'avg': '0.00%',
            'inqueues': 
                'total': 2,
                'active': 0
            ,
            'total': 0,
            'raw': '',
            'all': '',
            'strategy': None
        ,
        'timeouts': [0, 0],
        'processes': [28728, 28729]
    ,
    'pid': 28722,
    'rusage': 
        'stime': 0.3959,
        'idrss': 0,
        'maxrss': 57220,
        'inblock': 2552,
        'minflt': 24279,
        'majflt': 3,
        'msgsnd': 0,
        'ixrss': 0,
        'nswap': 0,
        'nivcsw': 31,
        'isrss': 0,
        'nvcsw': 3326,
        'utime': 2.492,
        'msgrcv': 0,
        'nsignals': 0,
        'oublock': 0
    

【问题讨论】:

【参考方案1】:

您在 app.conf.update() 调用中明确设置了 CELERY_ALWAYS_EAGER=True (docs for 3.1),因此 Celery 以同步模式执行。

它已被弃用并重命名为 task_always_eager (docs for latest 4.2) 但仍可能被您的 Celery v4.2 识别

【讨论】:

以上是关于Celery .delay() 同步工作,不延迟的主要内容,如果未能解决你的问题,请参考以下文章

celery delay 没反应

使用 Mandrill send_at 或 Celery countdown/eta 延迟发送电子邮件

Celery 收下这捆芹菜!

在没有工人的情况下运行 celery 任务

FPGA中的delay与latency

合并复制可以以 0 毫秒的延迟运行,即实时吗?