Celery - 从特定时间开始定期调度任务

6 投票
2 回答
8967 浏览
提问于 2025-04-17 04:45

如何在特定时间安排一个定期任务,最好的方法是什么?

(我不打算用cron来做这个,因为我需要安排大约一百个远程的rsync任务, 我需要计算远程和本地的时间差,并且需要在每个主机生成日志的那一秒就进行rsync。)

根据我的理解,celery.task.schedules中的crontab类只能指定小时、分钟和星期几。 到目前为止,我找到的最有用的建议是nosklo的这个回答

这是最好的解决方案吗? 我是不是在用错工具?

2 个回答

-1

我最近在做一个任务,涉及到Celery这个工具。我需要用它来处理异步操作和定时任务。简单来说,我还是回到了老办法,使用了crontab来处理定时任务,虽然它实际上是调用一个Python脚本,这个脚本会启动一个单独的异步任务。这样做的好处是我需要维护的crontab就少了(因为要让Celery的调度器运行还需要一些额外的设置),但我可以充分利用Celery的异步功能。

12

Celery看起来是解决你调度问题的好工具:Celery的周期性任务可以精确到秒。

你用的工具是合适的,但crontab的设置并不是你想要的。你应该使用Python的datetime.timedelta对象;因为celery.schedules中的crontab调度器只能精确到分钟,而使用timedelta来配置周期性任务的间隔可以提供更强大的功能,这样就可以精确到秒。

比如,来自Celery的文档:

>>> from celery.task import tasks, PeriodicTask
>>> from datetime import timedelta
>>> class EveryThirtySecondsTask(PeriodicTask):
...     run_every = timedelta(seconds=30)
...
...     def run(self, **kwargs):
...         logger = self.get_logger(**kwargs)
...         logger.info("Execute every 30 seconds")

http://ask.github.com/celery/reference/celery.task.base.html#celery.task.base.PeriodicTask

class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

这里唯一的挑战是,你需要描述这个任务运行的频率,而不是你希望它在什么具体时间运行;不过,我建议你看看高级Python调度器 http://packages.python.org/APScheduler/

看起来高级Python调度器可以很方便地用来按照你选择的任何时间表来启动普通的(即非周期性)Celery任务,利用它自己的调度功能。

撰写回答