Python定时库APScheduler&Django使用django-apscheduler实现定时任务

提示:以下是本篇文章正文内容,下面案例可供参考

一、定时任务简介

定时任务, linux 自带的 crontab ,windows 自带的任务计划,都可以实现守时任务。没错,操作系统基本都会提供定时任务的实现,但是如果你想要更加精细化的控制,或者说任务程序需要跨平台运行,最好还是自己实现定时任务框架,Python 的 apscheduler 提供了非常丰富而且方便易用的定时任务接口。本文两种方式实现定时任务。可以直接参考目录三Django中使用django-apscheduler,目录二内容测试已通过,相关数据库配置暂时无空尝试。

二、定时库APScheduler的使用

2.1 APScheduler简介

APscheduler全称Advanced Python Scheduler 作用为在指定的时间规则执行指定的作业。

apscheduler的四大组件,分别是Triggers,Job stores,Executors,Schedulers

  • triggers 触发器 可以按照日期、时间间隔或者contab表达式三种方式触发
  • job stores 作业存储器 指定作业存放的位置,默认保存在内存,也可以保存在各种数据库中
  • executors 执行器 将指定的作业提交到线程池或者进程池中运行
  • schedulers 作业调度器 常用的有BackgroundScheduler(后台运行)和BlockingScheduler(阻塞式)

Scheduler添加job流程
在这里插入图片描述
Scheduler调度流程
在这里插入图片描述

触发器(triggers):触发器包含调度逻辑,描述一个任务何时被触发,按日期或按时间间隔或按 cronjob 表达式三种方式触发。每个作业都有它自己的触发器,除了初始配置之外,触发器是完全无状态的。

(1). cron定时调度
year (int|str) – 4-digit year
month (int|str) – month (1-12)
day (int|str) – day of the (1-31)
week (int|str) – ISO week (1-53)
day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun)
hour (int|str) – hour (0-23)
minute (int|str) – minute (0-59)
second (int|str) – second (0-59)
start_date (datetime|str) – earliest possible date/time to trigger on (inclusive)
end_date (datetime|str) – latest possible date/time to trigger on (inclusive)
timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone)
和Linux的Crontab一样,它的值格式为
在这里插入图片描述
(2). interval 间隔调度
它的参数如下:
weeks (int) – number of weeks to wait
days (int) – number of days to wait
hours (int) – number of hours to wait
minutes (int) – number of minutes to wait
seconds (int) – number of seconds to wait
start_date (datetime|str) – starting point for the interval calculation
end_date (datetime|str) – latest possible date/time to trigger on
timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations

sched.add_job(job_function, ‘cron’, day_of_week=‘mon-fri’, hour=5, minute=30, end_date=‘2014-05-30’)

(3). date 定时调度
最基本的一种调度,作业只会执行一次。它的参数如下:
run_date (datetime|str) – the date/time to run the job at
timezone (datetime.tzinfo|str) – time zone for run_date if it doesn’t have one already

代码如下(示例):

# coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime


def aps_test(x):
    print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x)


scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
scheduler.add_job(func=aps_test, args=('一次性任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12))
scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3)

scheduler.start()

运行结果如下:
在这里插入图片描述
目前APScheduler支持触发器:

//具体的一次性任务 
DateTrigger  
//指定间隔时间
IntervalTrigger
//表示定时任务
CronTrigger

2.2 代码实践

from apscheduler.schedulers.background import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.interval import IntervalTrigger
import time


def my_job():
    print('my_job, {}'.format(time.ctime()))


if __name__ == "__main__":
    scheduler = BlockingScheduler()
    # 在某一个时间点执行
    # intervalTrigger = DateTrigger(run_date='2020-12-16 16:55:06')
    # 第一秒执行作业
     intervalTrigger = CronTrigger(second=1)
    # 每天的19:30:01执行作业
    # intervalTrigger = CronTrigger(hour=19, minute=30, second=1)
	# 每年的10119点执行作业 
	# intervalTrigger=CronTrigger(month=10, day=1, hour=19)

    scheduler.add_job(my_job, intervalTrigger, id='my_job_id')
    scheduler.start()

运行结果如下:
在这里插入图片描述

执行器(executors):执行器是将指定的作业(调用函数)提交到线程池或进程池中运行,当任务完成时,执行器通知调度器触发相应的事件。

目前APScheduler支持的Executor:

AsyncIOExecutor
GeventExecutor
ThreadPoolExecutor
ProcessPoolExecutor
TornadoExecutor
TwistedExecutor

作业存储器(job stores):作业存储器指定了作业被存放的位置,默认情况下作业保存在内存,也可将作业保存在各种数据库中,当作业被存放在数据库中时,它会被序列化,当被重新加载时会反序列化。作业存储器充当保存、加载、更新和查找作业的中间商。在调度器之间不能共享作业存储。

目前APScheduler支持的Jobstore:

MemoryJobStore
MongoDBJobStore
RedisJobStore
RethinkDBJobStore
SQLAlchemyJobStore
ZooKeeperJobStore

调度器(schedulers):任务调度器,属于控制角色,通过它配置作业存储器、执行器和触发器,添加、修改和删除任务。调度器协调触发器、作业存储器、执行器的运行,通常只有一个调度程序运行在应用程序中,开发人员通常不需要直接处理作业存储器、执行器或触发器,配置作业存储器和执行器是通过调度器来完成的。

目前APScheduler支持的Scheduler:

AsyncIOScheduler
BackgroundScheduler
BlockingScheduler
GeventScheduler
QtScheduler
TornadoScheduler
TwistedScheduler

三 Django中使用django-apscheduler

官网:https://github.com/jarekwg/django-apscheduler

3.1 安装模块

pip install django-apscheduler 

3.2 配置

(1)修改settings.py文件,在INSTALLED_APPS中加入django-apscheduler应用:

INSTALLED_APPS = [
    ......
    'django_apscheduler',#定时执行任务
]

继续加入

APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a"  # Default

(2)执行迁移命令:python manage.py migrate

   数据库中生产两个表
1. django_apscheduler_djangojob
2. django_apscheduler_djangojobexecution
//status: 执行状态
//duration: 执行了多长时间
//exception: 是否出现了什么异常

在这里插入图片描述

3.3 使用

在任意一个views.py文件中加入实现代码,使得每次启动Django框架时,定时任务都会同时启动。代码如下:

from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job
import time

#开启定时工作
try:
    # 实例化调度器
    scheduler = BackgroundScheduler()
    # 调度器使用DjangoJobStore()
    scheduler.add_jobstore(DjangoJobStore(), "default")
    # 设置定时任务,选择方式为interval,时间间隔为10s
    # 另一种方式为每天固定时间执行任务,对应代码为:
    # @register_job(scheduler, 'cron', day_of_week='mon-fri', hour='9', minute='30', second='10',id='task_time')
    @register_job(scheduler,"interval", seconds=10)
    def my_job():
        # 这里写你要执行的任务
        # pass
        print('my_job, {}'.format(time.ctime()))
    register_events(scheduler)
    scheduler.start()
except Exception as e:
    print(e)
    # 有错误就停止定时器
    scheduler.shutdown()
    

参数

scheduler: 指定调度器
trigger: 任务执行的方式,共有三种:'date''interval''cron''date' + 'run_date' 的参数组合, 能实现单次任务。
例子:2019-07-07 22:49:00 执行任务
@register_job(scheduler, 'date', id='test', run_date='2019-07-07 22:49:00')
注:在亲测时,执行完任务会报错,原因时执行完任务后会去mysql中删除djangojob表中的任务。但是djangojobexecution表记录着执行结果,有外键关联着djangojob表,所以删除时显示有外键约束错误。但是任务会正常执行,执行之后也会正常删除。
'interval' + 'hours' + 'minutes' + ..... 的参数组合,能实现间隔性任务。
例子:每隔3个半小时执行任务

还有seconds,days参数可以选择
注:如果任务需要执行10秒,而间隔设置为1秒,它是不会给你开10个线程同时去执行10个任务的。它会错过其他任务直到当前任务完成。
@register_job(scheduler, 'interval', id='test', hours=3, minutes=30)
'cron' + 'hour' + 'minute'+...的参数组合,能实现cron类的任务。
例子:每天的8点半执行任务

还有day,second,month等参数可以选择。
@register_job(scheduler, 'cron', id='test', hour=8, minute=30)
id: 任务的名字,不传的话会自动生成。不过为了之后对任务进行暂停、开启、删除等操作,建议给一个名字。并且是唯一的,如果多个任务取一个名字,之前的任务就会被覆盖。
args: list类型。执行代码所需要的参数。
next_run_time:datetime类型。开始执行时间。

在项目的urls.py文件中导入刚才新建的app的views(关键的一步,请点赞)

from apps.scripts import views

运行结果如下:
在这里插入图片描述


猜你喜欢

转载自blog.csdn.net/qq_35911309/article/details/111272304