Django结合Celery实现动态周期任务调度方案

顾言
顾言
发布时间:2026-10-13 | 6人浏览过
原创

本文介绍在腾讯蓝鲸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动态设置周期任务执行时间的内容即为分享的全部,希望能对大家有所帮助,也希望大家多多支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表