Django 自定义celery-beat调度器,查询自定义表的Cron表达式进行任务调度

学习目标:

通过自定义的CronScheduler调度器在兼容标准的调度器的情况下,查询自定义任务表去生成调度任务并分配给celery worker进行执行

不了解Celery框架的小伙伴可以先看一下我的上一篇文章:Celery框架组件分析及使用


学习内容:

  1. 创建自定义的Scheduler,设置自定义的Scheduler实现对原有配置的定时任务的兼容
  2. 如何启动自定义Scheduler对任务进行调度
  3. 创建自定义Scheduler遇到的一些问题

如何创建自定义的Scheduler:

在创建自定义Scheduler之前,我们先了解一下Scheduler类,这个类是Celery Beat的核心类,维护了任务的创建逻辑,调度逻辑。入下图是整个celery-beat启动执行流程图

     +---------------------+
     | Celery Beat 启动    |
     +----------+----------+
                |
                v
     +----------+----------+
     | Service.start()     |  --> 初始化 Scheduler(此时调用 setup_schedule)
     +----------+----------+
                |
                v
     +----------+----------+
     | scheduler.tick()    | 每隔 interval 触发一次,把当前任务按最近执行时间放入 _heap(调度堆)
     +----------+----------+
                |
                v
     +--------------------------+
     | schedule.get_schedule()  |
     | 返回所有任务 ScheduleEntry | 此处会获取所有的可执行的调度任务,需要重写
     +--------------------------+
                |
                v
     +-----------------------------+
     | entry.is_due()              |
     | 判断任务是否需要执行		   |
     +-----------------------------+
                |
     如果是 True           否则等待下次 tick
                |
                v
     +-----------------------------+
     | apply_async(entry)          |
     | 发出任务执行                  |
     +-----------------------------+

要定义一个DjangoCronScheduler继承Scheduler,需要封装自己的数据库Cron表达式数据加载逻辑

import logging
import re

from celery.beat import Scheduler, ScheduleEntry
from celery.schedules import crontab
from django.db import close_old_connections

from record.models import KeywordVideoSchedule, AccountVideoSchedule

logger = logging.getLogger(__name__)


class DjangoCronScheduler(Scheduler):
    """从Django模型动态加载cron任务的调度器"""

    def __init__(self, *args, **kwargs):
        self._schedule = {
   
   }
        self._cron_schedule = {
   
   }
        self._last_refresh = None
        self._refresh_interval = kwargs.pop('refresh_interval', 3600)  # 默认3600秒刷新一次
        super().__init__(*args, **kwargs)
	
	# 第一步,初始化所有的动态cron表达式的任务
    def setup_schedule(self):
        """初始化调度"""
        super().setup_schedule()
        # 加载静态配置中的任务(即 app.conf.beat_schedule)
        for name, entry in self.app.conf.beat_schedule.items():
            if isinstance(entry, dict):
                self._schedule[name] = self.Entry(
                    name=name,
                    task=entry['task'],
                    schedule=entry['schedule'],
                    args=entry.get('args', []),
                    kwargs
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值