学习目标:
通过自定义的CronScheduler调度器在兼容标准的调度器的情况下,查询自定义任务表去生成调度任务并分配给celery worker进行执行
不了解Celery框架的小伙伴可以先看一下我的上一篇文章:Celery框架组件分析及使用
学习内容:
- 创建自定义的Scheduler,设置自定义的Scheduler实现对原有配置的定时任务的兼容
- 如何启动自定义Scheduler对任务进行调度
- 创建自定义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

最低0.47元/天 解锁文章
2531

被折叠的 条评论
为什么被折叠?



