如何使用Celerybeat和Flask设置定期任务,每小时查询一次数据库?
环境如下:
/
|-app
|-__init__.py
|-jobs
|-task.py
|-celery-beat.sh
|-celery-worker.sh
|-manage.py
我目前在run_query()
task.py
的查询功能
我希望调度程序在应用程序启动后启动,所以我在/app/__init__.py
文件夹中有以下行:
celery = Celery()
@celery.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(1, app.jobs.task.run_query())
(为了简单起见,我已将其设置为如果它运行,它将每分钟运行。还没有运气。)
当我启动celery-worker.sh
时,它会在[tasks]
标题下识别我的功能。但计划功能永远不会运行。我可以通过在命令提示符处发出以下命令来手动强制运行该函数:
>> from app.jobs import task
>> task.run_query.delay()
编辑:添加了celerybeat.sh
作为后续:如果通过烧瓶上下文访问数据库,在我的异步函数调用期间创建一个新的烧瓶上下文来访问数据库是明智的吗?使用现有的烧瓶背景?或者完全忘记上下文并只是启动与数据库的连接?我担心的是,如果我只是发起一个新连接,它可能会干扰现有的上下文连接?
答案 0 :(得分:3)
要执行定期任务,您需要某种调度程序(例如芹菜节拍)。
芹菜击败是一个调度程序;它定期启动任务,然后由可用的工作节点执行 群集。
您必须确保只有一个调度程序正在运行以进行计划 一次,否则你最终会遇到重复的任务。用一个 集中式方法意味着时间表不一定如此 同步,服务可以在不使用锁的情况下运行。
您可以使用命令
调用调度程序$ celery -A proj beat #different process from your worker
您还可以通过启用工作人员-B在工作人员中嵌入节拍 选项,如果您永远不会运行多个工作人员,这很方便 节点,但它并不常用,因此不建议这样做 用于生产用途启动调度程序:
$ celery -A proj worker -B