10

我想要一个每 5 分钟执行一次的任务,但它会等待最后一次执行完成,然后开始计算这 5 分钟。(这样我也可以确定只有一个任务在运行)我发现最简单的方法是运行 django application manage.py shell 并运行这个:

while True:
    result = task.delay()
    result.wait()
    sleep(5)

但是对于我想以这种方式执行的每个任务,我都必须运行它自己的 shell,有没有简单的方法可以做到这一点?可能是一些国王定制 ot django celery 调度程序?

4

6 回答 6

18

哇,令人惊讶的是没有人理解这个人的问题。他们问的不是定期运行任务,而是如何确保 Celery 不会同时运行同一任务的两个实例。我认为没有办法直接使用 Celery 执行此操作,但是您可以做的是让其中一个任务在开始时立即获得锁定,如果失败,请在几秒钟内重试(使用重试) . 该任务将在它返回之前释放锁;如果它崩溃或超时,你可以让锁在几分钟后自动过期。

对于锁,您可能只使用您的数据库或 Redis 之类的东西。

于 2013-07-12T00:23:22.813 回答
16

您可能对这种不需要更改 celery conf 的简单方法感兴趣。

@celery.decorators.periodic_task(run_every=datetime.timedelta(minutes=5))
def my_task():
    # Insert fun-stuff here
于 2011-04-27T04:56:26.513 回答
12

您所需要的只是在 celery conf 女巫任务中指定您想要定期运行以及以哪个间隔运行。

示例:每 30 秒运行一次 tasks.add 任务

from datetime import timedelta

CELERYBEAT_SCHEDULE = {
    "runs-every-30-seconds": {
        "task": "tasks.add",
        "schedule": timedelta(seconds=30),
        "args": (16, 16)
     },
}

请记住,您必须使用 -B 选项在节拍模式下运行 celery

manage celeryd -B

您还可以使用 crontab 样式而不是时间间隔,请查看:

http://ask.github.com/celery/userguide/periodic-tasks.html

如果您使用 django-celery,请记住您也可以使用 tha django db 作为定期任务的调度程序,这样您可以轻松地通过 django-celery 管理面板添加新的定期任务。为此,您需要以这种方式在 settings.py 中设置 celerybeat 调度程序

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
于 2011-03-19T10:50:41.723 回答
4

要扩展 @MauroRocco 的帖子,来自http://docs.celeryproject.org/en/v2.2.4/userguide/periodic-tasks.html

使用 timedelta 作为计划意味着任务将在 celerybeat 启动后 30 秒执行,然后在最后一次运行后每 30 秒执行一次。也存在类似 crontab 的计划,请参阅有关 Crontab 计划的部分。

所以这确实会达到你想要的目标。

于 2011-03-19T16:18:55.150 回答
2

由于不推荐使用 celery.decorators,您可以像这样使用periodic_task 装饰器:

from celery.task.base import periodic_task
from django.utils.timezone import timedelta

@periodic_task(run_every=timedelta(seconds=5))
def my_background_process():
    # insert code
于 2013-05-05T15:38:27.580 回答
0

将该任务添加到单独的队列中,然后对该队列使用单独的工作程序,并将并发选项设置为 1。

于 2016-02-15T11:32:29.093 回答