Celery 任务计划(Celery、Django 和 RabbitMQ)

发布于 2024-10-24 06:50:57 字数 315 浏览 1 评论 0原文

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

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

但是对于我想以这种方式执行的每个任务,我必须运行它自己的shell,有简单的方法吗?可能是一些 King Custom ot django celery 调度程序?

I want to have a task that will execute every 5 minutes, but it will wait for last execution to finish and then start to count this 5 minutes. (This way I can also be sure that there is only one task running) The easiest way I found is to run django application manage.py shell and run this:

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

but for each task that I want to execute this way I have to run it's own shell, is there an easy way to do it? May be some king custom ot django celery scheduler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月下客 2024-10-31 06:50:57

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

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

Wow it's amazing how no one understands this person's question. They are asking not about running tasks periodically, but how to ensure that Celery does not run two instances of the same task simultaneously. I don't think there's a way to do this with Celery directly, but what you can do is have one of the tasks acquire a lock right when it begins, and if it fails, to try again in a few seconds (using retry). The task would release the lock right before it returns; you can make the lock auto-expire after a few minutes if it ever crashes or times out.

For the lock you can probably just use your database or something like Redis.

暗地喜欢 2024-10-31 06:50:57

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

@celery.decorators.periodic_task(run_every=datetime.timedelta(minutes=5))
def my_task():
    # Insert fun-stuff here

You may be interested in this simpler method that requires no changes to a celery conf.

@celery.decorators.periodic_task(run_every=datetime.timedelta(minutes=5))
def my_task():
    # Insert fun-stuff here
ぇ气 2024-10-31 06:50:57

您所需要的只是在 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 请记住,您还可以使用 django db 作为定期任务的调度程序,这样您可以轻松地通过 django-celery 管理面板添加新的定期任务。
为此,您需要以这种方式在 settings.py 中设置 celerybeat 调度程序

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"

All you need is specify in celery conf witch task you want to run periodically and with which interval.

Example: Run the tasks.add task every 30 seconds

from datetime import timedelta

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

Remember that you have to run celery in beat mode with the -B option

manage celeryd -B

You can also use the crontab style instead of time interval, checkout this:

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

If you are using django-celery remember that you can also use tha django db as scheduler for periodic tasks, in this way you can easily add trough the django-celery admin panel new periodic tasks.
For do that you need to set the celerybeat scheduler in settings.py in this way

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
甜妞爱困 2024-10-31 06:50:57

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

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

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

To expand on @MauroRocco's post, from http://docs.celeryproject.org/en/v2.2.4/userguide/periodic-tasks.html

Using a timedelta for the schedule means the task will be executed 30 seconds after celerybeat starts, and then every 30 seconds after the last run. A crontab like schedule also exists, see the section on Crontab schedules.

So this will indeed achieve the goal you want.

○闲身 2024-10-31 06:50:57

由于 celery.decorators 已弃用,您可以使用 periodical_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

Because of celery.decorators deprecated, you can use periodic_task decorator like that:

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
失与倦" 2024-10-31 06:50:57

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

Add that task to a separate queue, and then use a separate worker for that queue with the concurrency option set to 1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文