Django结合Celery实现动态周期任务调度方案
本文介绍在腾讯蓝鲸PaaS平台开发数据库巡检SaaS应用时,如何利用Django与Celery解决固定周期任务的局限性。通过动态创建CrontabSchedule和PeriodicTask,实现根据业务需求灵活调整巡检频率、时间及采样区间,并支持运行时动态启停任务,提升运维自动化效率。
蓝鲸PaaS平台应用开发实战经验分享
蓝鲸PaaS平台应用开发实战经验分享
腾讯蓝鲸智云提供了一套完整的PaaS技术解决方案,涵盖前后台开发框架、调度引擎及公共组件等模块,旨在协助业务产品和技术人员快速构建低成本、免运维的支撑工具与运营系统。
该PaaS平台不仅将应用服务的运行与开发环境以服务形式提供给开发者,还集成了组件系统、统一登录、权限管理、后台框架、MagicBox以及桌面工作台等高效便捷的开发服务。

平台支持多语言开发框架,使运维人员能够利用自身擅长的技术栈(如Python、Java等)在平台上开发运维自动化工具。
深入理解PaaS的设计理念后,运维人员可基于蓝鲸PaaS平台从零开始进行SaaS应用实战开发,快速构建企业级运维或运营系统,从而显著提升企业的自动化水平。
开发背景
开发背景
在某银行自动化运维项目中,客户要求在蓝鲸PaaS平台上开发一款数据库巡检SaaS应用。具体需求如下:
为确保数据库正常运行及数据的安全性、完整性和可用性,需开发自动化巡检工具以替代人工巡检。巡检周期窗口划分为四类:日巡检、周巡检、月巡检及半年度巡检。
日巡检维护指每日按计划执行的巡检活动,主要检查数据库运行状态、备份状态及告警错误。
周巡检维护指以一周为周期,在每周指定日期执行的巡检活动。其工作内容在日巡检基础上,增加数据库对象检查及安全性检查等内容。
月巡检维护指以一月为周期,在每月指定日期执行的巡检活动。其工作内容在周巡检基础上,增加系统参数配置检查、硬件与系统平台运行状态检查等内容。
半年度/年度巡检维护指以半年或一年为周期,在指定日期执行的巡检活动。其工作内容在月巡检基础上,增加数据库性能诊断检查。
巡检实现方式分为两种:
1、立即巡检
用户首先选择目标业务下的主机及需巡检的数据库实例(支持多选),并设置数据采样区间(当前时间之前的任意时间段)。

点击立即巡检按钮,等待数秒后巡检完成。用户可点击查看详情或导出报告。

2、定时巡检
用户可根据需求设置每天、每周或每月执行巡检任务。以每周为例,用户需配置某业务下的主机、数据库实例、巡检频率、巡检时长(任意天数)及执行时间(每周某一天的具体时刻),如下图所示:

实现方式
实现方式
针对上述需求,常规开发中使用periodic_task装饰器,程序启动后自动执行周期任务:
固定周期任务示例
@periodic_task(run_every=crontab(minute='*/5', hour='*', day_of_week="*"))
def get_time():
"""
celery 周期任务示例
run_every=crontab(minute='*/5', hour='*', day_of_week="*"):每 5 分钟执行一次任务
"""
now = datetime.datetime.now()
logger.error(u"celery 周期任务调用成功,当前时间:{}".format(now))
crontab()实例化时若未设置参数,则使用默认值。crontab共有7个参数,常用的5个参数分别为:
minute:分钟,范围0-59
hour:小时,范围0-23
day_of_week:星期几,范围0-6。以星期天为起始,即0代表星期天。该参数也可使用英文缩写表示,例如“sun”代表星期天。
day_of_month:每月第几号,范围1-31
month_of_year:月份,范围1-12
上述方案存在以下弊端:
每次需根据巡检是周几来计算数据采样区间的具体时间,再触发定时任务,可能存在误差。
此外,传统定时任务无法直接取消。
举例说明,若客户选择每周三早上8点执行任务,采样区间为3天。假设首次于10月1日8:00执行任务,触发定时任务获取9月28日8:00至10月1日8:00之间的数据;随后再次执行时间为10月8日,再次触发定时任务并循环执行。
最终通过以下方式解决该问题:
模板函数提前开发完成,并添加@task()装饰器:
模板函数定义
@task()
def auto_iip(**kwargs):
logger.error(kwargs)
'此处写逻辑代码'
测试每分钟执行一次,启动工程及Celery,调用上述函数,确认OK,等待1分钟后执行成功。
动态任务创建逻辑
from djcelery.models import PeriodicTask, CrontabSchedule
from djcelery.schedulers import ModelEntry, DatabaseScheduler
def test_celery_task(date_data):
crontab= CrontabSchedule.objects.create(
hour='*',
minute='*/1',
day_of_week='*',
day_of_month='*',
month_of_year="*"
)
schedule = crontab.schedule
create_or_update_task = DatabaseScheduler.create_or_update_task
#'home_application.celery_tasks.auto_iip' home模块下的task。
task_template='home_application.celery_tasks.auto_iip'
#task_name自定义,不能重复。
task_name = 'test'
schedule_dict = {
'schedule': schedule,
'args': [],
'kwargs': data,
'task': task_template,
'enabled': 1
}
create_or_update_task(task_name, **schedule_dict)
停止定时任务时,可直接根据task_name进行删除。
动态任务删除逻辑
def delete_celery_task(task_name):
DatabaseScheduler.delete_task(task_name)
操作完成。
以上关于Django实现Celery动态设置周期任务执行时间的内容即为分享的全部,希望能对大家有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









